您好我正在尝试编写一个程序,它将在运行时创建内存,这样程序可以连续运行,因为它生成内存来存储字符串,直到用户决定退出。但是,当我运行程序时,我可以正确输入字符串,但打印出来是另一个故事。我相信问题是在循环中我覆盖了每次迭代创建的内存。以下是我到目前为止的情况:
int main(){
char **lines = NULL;
char sentence[1000];
int numOfLines = 1;
int i;
int j;
printf("Enter the sentence:\n");
lines = (lines, numOfLines * sizeof *lines);
for (i=0; i <= numOfLines; i++){
fgets(sentence, 1000, stdin);
lines[i] = malloc (sizeof(char) * strlen(sentence) +1);
if (strcmp(sentence, ".\n") == 0){ //exits loops if entered string is "."
break;
}
strcpy(lines[i], sentence);
numOfLines++;
printf("%s", lines[i]); // attempt at a Debug statement
}
numOfLines = numOfLines - 1;
for (j = numOfLines; j>=0; j--){ //prints out the lines in reverse
printf("%s\n", lines[j]);
}
return 0;
}
我可能会补充说,当用户退出循环时,我会遇到分段错误。
答案 0 :(得分:2)
lines[i] = malloc (sizeof(char) * strlen(sentence + 1));
这是一个问题。应该是
lines[i] = malloc (sizeof(char) * strlen(sentence) + 1);
答案 1 :(得分:1)
问题
您在每个循环中执行此操作
0
如果您退出未使用的早期行充满随机gunk
尝试(注意:修复NYI&#39;)
lines = malloc(sizeof(char *) * numOfLines);
请注意,您需要设置最大值并在达到最大值之前退出循环,或者让用户输入最大值并动态设置。
答案 2 :(得分:1)
lines = malloc(sizeof(char *) * numOfLines);
在每次迭代中,您将分配一个全新的数组,而旧的数组将丢失(未释放,不再可寻址)。你想要的是 realloc (3)。
lines[i] = malloc (sizeof(char) * strlen(sentence + 1));
如Andrew Jenkins所述,您需要strlen(sentence) + 1
。您的代码分配的字节数比您需要的少2个。 (考虑sentence + 1
是什么。)一个容易出错的习语是1 + strlen(sentence)
。
Posix定义了一个更方便的函数strdup
(3),它有助于避免这种fencepost错误。
如果我愿意,可以提出一个建议:您没有检查您的分配是否返回有效值。即使现在存储器很大(并且在Linux上,通常比实际更大),正确的逻辑处理来自任何函数调用的错误。
答案 3 :(得分:1)
另一种修改代码的方法是改变:
lines = malloc(sizeof(char *) * numOfLines);
为:
lines = realloc(lines, numOfLines * sizeof *lines);
(注意,我使用sizeof
char **lines = NULL;
来提高代码的健壮性。并且在循环之前有malloc
。
然后,根据需要增加包含行指针的内存块的大小。
请注意,您应检查realloc
和__LINE__
的返回值,并在返回NULL时采取适当的操作。如果您希望能够在realloc失败的情况下恢复该程序,recommended idiom。