C - 在程序运行时分配内存



嗨,我正在尝试编写一个将在运行时创建内存的程序,以便该程序可以在生成内存以存储字符串时连续运行,直到用户决定退出。但是,当我运行程序时,我可以正确输入字符串,但是打印出来是另一回事。我相信问题是在循环中我覆盖了通过每次迭代创建的内存。这是我到目前为止所拥有的:

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("%sn", lines[j]);
   }
   return 0;
}

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

lines[i] = malloc (sizeof(char) * strlen(sentence + 1));

这是一个问题。应该是

lines[i] = malloc (sizeof(char) * strlen(sentence) + 1);

问题

您可以在每个循环中执行此操作

lines = malloc(sizeof(char *) * numOfLines); 

如果你退出早期不使用的线路充满了随机的垃圾

尝试(注意:修复纽约指数)

#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
int main(){
    char sentence[1000]; // NYI - fix magic
    int numOfLines = 0;
    int maxNumOfLines = 10;
    char **lines=malloc(sizeof(char *) * maxNumOfLines); // NYI - calloc
    bzero(lines, sizeof(char *) * maxNumOfLines); // NYI - calloc
    printf("Enter the sentence:n");
    for (int i=0; i < maxNumOfLines; i++) { 
      fgets(sentence, 1000, stdin);
      lines[i] = malloc (sizeof(char) * strlen(sentence) + 1);
      if (strcmp(sentence, ".n") == 0){
        strcpy(lines[i], ".n");
        break;
      }
      strcpy(lines[i], sentence);
      numOfLines++;
      //printf("%s", lines[i]); // intial Debug statement
    }
    for (int j = numOfLines-1; j>=0; j--){
      printf("%sn", lines[j]);
    }
    return 0;
}

请注意,您需要设置最大值并在达到最大值之前退出循环,或者让用户输入最大值并动态设置它。

 lines = malloc(sizeof(char *) * numOfLines); 

在每次迭代中,您都会分配一个全新的数组,而旧数组将丢失(未释放,并且不再可寻址)。 这里你想要的是 realloc(3)。

 lines[i] = malloc (sizeof(char) * strlen(sentence + 1));

正如安德鲁詹金斯提到的,你想要strlen(sentence) + 1。 您的代码分配的字节比您需要的少 2 个字节。 (考虑一下sentence + 1是什么。 一个不太容易出错的成语是1 + strlen(sentence) .

Posix 定义了一个更方便的功能,strdup (3),有助于避免这种栅栏错误。

如果可以的话,有一句忠告:您没有检查您的分配是否返回有效值。 尽管现在内存很大(在 Linux 上,内存通常比实际内存大),但正确的逻辑处理来自任何函数调用的错误。

修复代码的另一种方法(尚未提及)是更改:

lines = malloc(sizeof(char *) * numOfLines); 

自:

lines = realloc(lines, numOfLines * sizeof *lines);

(注意,我使用推荐的sizeof习语来提高代码健壮性)。并在循环之前,char **lines = NULL;.

然后,包含行指针的内存块将根据需要增加大小。

请注意,您应该检查 mallocrealloc 的返回值,如果它返回 NULL,则采取适当的操作。如果您希望能够在 realloc 发生故障的情况下恢复程序,请参阅此处。

相关内容

  • 没有找到相关文章

最新更新