在程序运行时分配内存

时间:2017-01-31 02:00:09

标签: c loops memory malloc

您好我正在尝试编写一个程序,它将在运行时创建内存,这样程序可以连续运行,因为它生成内存来存储字符串,直到用户决定退出。但是,当我运行程序时,我可以正确输入字符串,但打印出来是另一个故事。我相信问题是在循环中我覆盖了每次迭代创建的内存。以下是我到目前为止的情况:

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;

}

我可能会补充说,当用户退出循环时,我会遇到分段错误。

4 个答案:

答案 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