简体   繁体   English

在程序运行时分配内存

[英]allocating memory as the program runs

Hi there I am trying to write a program that will create memory during run time, such that the program could run continuously as it generates memory to store strings until the user decides to quit. 嗨,我正在尝试编写一个在运行时创建内存的程序,以便该程序可以连续运行,因为它生成存储字符串的内存,直到用户决定退出为止。 However, when I run the program I can enter the strings properly, however printing them out is another story. 但是,当我运行程序时,我可以正确输入字符串,但是将它们打印出来是另一回事。 I believe the issue is that in the loop I am overwriting the memory that was created through each iteration. 我认为问题在于,在循环中,我将覆盖每次迭代创建的内存。 Here is what I have thus far: 到目前为止,这是我所拥有的:

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;

}

I might add that I get a segmentation fault when the user exits the loop. 我可能会补充说,当用户退出循环时会出现分段错误。

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

This is a problem. 这是个问题。 Should be 应该

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

Issues 问题

You do this on each loop 您在每个循环中执行此操作

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

If you exit early lines not used are full of random gunk 如果您退出未使用的早线,则充满了乱七八糟的局面

Try (Note: FIX the NYI's) 试试(注意:修复NYI)

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

}

Note that you need to either set a maximum and exit the loop before that max is reached or get the user to enter the maximum and set it dynamically. 请注意,您需要设置一个最大值并在达到该最大值之前退出循环,或者让用户输入最大值并动态设置它。

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

On each iteration, you're allocating a completely new array, and the old one is lost (not freed, and no longer addressable). 在每次迭代中,您将分配一个全新的数组,而旧的数组将丢失(无法释放,并且不再可寻址)。 What you want here is realloc (3). 您想要的是重新分配 (3)。

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

As Andrew Jenkins mentions, you want strlen(sentence) + 1 . 正如安德鲁·詹金斯Andrew Jenkins)所提到的,您想要strlen(sentence) + 1 Your code is allocating 2 fewer bytes than you need. 您的代码分配的字节数比所需少2个。 (Consider what sentence + 1 is.) A less error-prone idiom is 1 + strlen(sentence) . (考虑什么sentence + 1是。)一个不太容易出错的习惯用法是1 + strlen(sentence)

Posix defines a more convenient function, strdup (3), that helps avoid this kind of fencepost error. Posix定义了一个更方便的函数strdup (3),可帮助避免这种击剑事件。

One word of advice, if I may: You're not checking that your allocations return a valid value. 一个建议,如果可能的话:您不是在检查分配是否返回有效值。 Even though memories are big nowadays (and, on Linux, frequently bigger than actual) correct logic deals with errors from any function call. 即使现在的内存很大(在L​​inux上,内存通常大于实际的内存),正确的逻辑也可以处理任何函数调用中的错误。

Another way to fix your code, not mentioned yet, is to change: 尚未修改的另一种修复代码的方法是更改​​:

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

to: 至:

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

(Note, I use the recommended idiom for sizeof to increase code robustness). (请注意,我对sizeof使用推荐的惯用法来提高代码的健壮性)。 And have before the loop, char **lines = NULL; 并且在循环之前有char **lines = NULL; .

Then the memory block containing the line pointers will be increased in size as necessary. 然后,包含行指针的存储块将根据需要增加大小。

Note that you should check the return value of malloc and realloc and take appropriate action if it returned NULL. 请注意,您应该检查mallocrealloc的返回值,并在返回NULL时采取适当的措施。 If you want to be able to recover the program in the case of realloc failure, see here . 如果您希望在重新分配失败的情况下能够恢复程序, 请参见此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM