[英]Allocating memory to char pointers
我在使用功能时遇到两个问题,一个非常阻碍,另一个问题并非如此。
我正在学习C语言以及以下(为便于阅读而简化)main语言,并且findWord函数应该将随机选择的单词从.txt文件存储到'wordToGuess'中。
findWord将该单词存储到指针“ wordToGuess”中很好,但是我似乎无法从函数中提取它以在主函数中使用它。 我试着将函数设为“ void”,然后直接在函数内修改“ wordToGuess”,然后将其设为char *,然后返回要由主用户使用的单词,但无济于事。 在任何情况下,int * wordLength都没有问题,这使我认为问题可能是由于对指针的潜在误解或内存分配造成的。
另一个不太重要的问题是free(wordToFind)使整个事情崩溃了,但是我对这个问题并不那么困惑。
谢谢你的帮助。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#define MIN 0
#define MAX 10
#define WORDSIZE 40
char* findWord(char *wordToGuess , int *wordLength);
int main(int argc , char *argv[])
{
int *wordLength = NULL , lengthWord = 0;
char *wordToGuess = NULL ;
srand(time(NULL)); // For rand() in findWord
wordLength = &lengthWord;
printf("\n1: %s\n" , findWord(wordToGuess , wordLength); // Sole purpose of this tester printf is to verify findWord function
return 0;
}
char* findWord(char *wordToGuess , int *wordLength)
{
int wordNumber = 0 , i = 0;
char word[WORDSIZE] = {0};
FILE *wordFile = NULL;
wordFile = fopen("words.txt" , "r");
if(wordFile != NULL)
{
wordNumber = (rand() % (MAX - MIN + 1)) + MIN; // Random number to choose word form words.txt
for(i = 0 ; i < wordNumber ; i++)
{
while(fgetc(wordFile) != '\n'); // Move the cursor to line 'wordNumber'
}
fgets(word , WORDSIZE , wordFile); // Get word from that line
}
*wordLength = strlen(word);
wordToGuess = malloc(*wordLength * sizeof(char));
if(wordToGuess == NULL)
exit(0);
wordToGuess = word;
fclose(wordFile);
// free(wordToGuess);
return wordToGuess;
}
您的代码有很多问题。 首先是C通过value传递参数,这意味着在将参数传递给函数时它们将被复制。 因此,在函数内,您所拥有的只是一个副本 ,修改副本当然不会修改原始副本。
C没有通过引用传递,但是可以使用指针进行模拟。 在您的情况下,您必须将指针传递给该指针。 可以使用运算符&
的地址来完成。 当然,您必须修改该函数,以便能够将指向指针的指针作为其第一个参数。
以某种方式,您现在可以使用wordLength
参数来执行此操作, 但是您将其声明为调用函数中的指针,并指向NULL
的指针,这意味着在函数内部对其进行取消引用将导致未定义的行为 。
所以有些正确的代码就像
char* findWord(char **wordToGuess , int *wordLength);
int main()
{
int wordLength = 0;
char *wordToGuess = NULL;
printf("%s\n", findWord(&wordToGuess, &wordLength));
// Note use of address-of operator
}
然后,在findWord
函数中,您当然必须将指针解除对字符串的引用,例如
*wordToGuess = malloc(...);
findWord
函数中还存在其他错误,例如您重新分配给指针而不是复制给它,这将使您失去分配的原始指针,并使其指向局部变量,并且一旦函数返回。 而是复制到内存中。
findWord
函数的另一个主要问题是您将一个字节分配给一点。 请记住,字符串包含的字符比strlen
报告的字符多一个,即字符串终止符'\\0'
。 分配内存时,必须为此字符添加空间。
分配时
wordToGuess = word;
您将句柄覆盖到分配的内存并有效地丢失了它。 更糟糕的是,使wordToGuess
指向从函数返回后就超出范围的本地数组。
您为返回的字符串分配内存的想法很好,但是您必须复制字符串的内容,而不是字符串地址:
strcpy(wordToGuess, word);
您必须为终止的空字符分配比strlen
多一个的char,这也将用strcpy
复制。
如果您的系统具有strdup
,则可以使用它来一次性分配和复制。
首先,您为字符串分配内存
wordToGuess = malloc(*wordLength * sizeof(char));
然后您立即覆盖指针
wordToGuess = word;
这意味着:
1)wordToGuess现在指向一个缓冲区,该缓冲区将在函数返回后立即失效
2)分配的内存现在是孤立的
你可能想要strcpy
您还必须为尾随的'\\ 0'分配内存,因此malloc( 1 + *wordLength )
请注意,每个定义的sizeof(char)
为1
这不是内存分配问题。 您已使用{0}初始化了数组,并尝试使用“ =”运算符进行分配。
数组值在C中不可修改,因此您不能只说:
wordToGuess = word;
您可以更改数组的内容,但不能通过执行类似pointer_a = pointer_b的操作来更改,而是在您的情况下使用strcpy:
strcpy(wordToGuess, word);
或strcpy_s ,它提供相同的结果,但是如果您正确指定目标缓冲区的大小,则不会导致缓冲区溢出。
您这里有两个重要的问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#define MIN 0
#define MAX 10
#define WORDSIZE 40
char* findWord(int *wordLength);
int main(int argc , char *argv[])
{
int lengthWord = 0;
char *wordToGuess;
srand(time(NULL)); // For rand() in findWord
wordToGuess = findWord(&lengthWord);
if (wordToGuess != NULL)
{
printf("\n1: %s\n" , wordToGuess); // Sole purpose of this tester printf is to verify findWord function
free(wordToGuess); // you should release resources.
}
return 0;
}
char* findWord(int *wordLength) // You don't need to pass wordToGuess as a parameter.
{
int wordNumber = 0 , i = 0;
char word[WORDSIZE] = {0};
char *wordToGuess;
FILE *wordFile = NULL;
wordFile = fopen("words.txt" , "r");
if(wordFile != NULL)
{
wordNumber = (rand() % (MAX - MIN + 1)) + MIN; // Random number to choose word form words.txt
for(i = 0 ; i < wordNumber ; i++)
{
while(fgetc(wordFile) != '\n'); // Move the cursor to line 'wordNumber'
}
fgets(word , WORDSIZE , wordFile); // Get word from that line
}
*wordLength = strlen(word);
//wordToGuess = malloc(*wordLength * sizeof(char)); // this is wrong
wordToGuess = malloc(*wordLength + 1); // sizeof(char) equals 1 always
if(wordToGuess == NULL)
exit(0);
// wordToGuess = word; this line is wrong, it should be
memcpy(wordToGuess, word, *wordLength);
wordToGuess[*wordLength] = '\0';
fclose(wordFile);
// free(wordToGuess);
return wordToGuess;
}
您应该始终为null
终止字节分配空间,并且应该学习指针的工作原理,因为很明显,您无法从wordToGuess = word;
理解它们wordToGuess = word;
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.