动态内存分配来自输入文件的数组字符串

时间:2015-11-03 22:06:41

标签: c dynamic-memory-allocation

嘿伙计我是C的一个相对较新的程序员,我试图简单地将输入文件中的内容打印到我的屏幕上。我必须使用动态内存分配,我面临的问题是,如果我的字符串中的字母数> 8,则会覆盖它。

int main(){
FILE *input = fopen("inpit.txt","r");
int b;
char **aPtr;
int i = 0;
int j = 0;
fscanf(input,"%d",&b); //takes first value from input file which tells me number of strings in the file
aPtr = (char **)malloc(sizeof(char *)*b); 
for(i=0;i<b;i++) {
    aPtr[i]=(char *)malloc(sizeof(char));
}
for(i = 0;i < b;i++){
    fscanf(input,"%s",&aPtr[i]);
}
for(i = 0;i < b;i++){
    printf("Address %d = %d\n",i,&aPtr[i]);
}

for(i = 0;i < b;i++){
    printf("%s\n",(aPtr+i));
}
return 0; }

我对inpit1.txt文件的输入是:

5
grapefruit
apple
Banana
monkey
orange

如果我运行该文件。除葡萄柚外,一切都会打印出来。哪个将被覆盖到葡萄柚。

任何帮助将不胜感激。提前谢谢。

4 个答案:

答案 0 :(得分:2)

你的malloc有问题,这里只分配一个char:

aPtr[i]=(char *)malloc(sizeof(char));

尝试为其添加指定尺寸:

aPtr[i]=(char *)malloc(sizeof(char)*20);

它应该更好用

关于malloc()投射的注意事项: 在c中不需要强制转换malloc()(除非处理过时的标准[1989年之前])并且可以隐藏错误。 void*会自动提升为任何其他指针类型。 但是,如果编译为C ++,那么它很有用,因为你的问题包括C和C ++,我认为最好告诉你它。

编辑:有关malloc()投射的更多信息,我刚刚找到了这个受保护的问题here。请随意查看。

此外,您需要检查malloc()是否成功(结果为!=NULL

最后你的printf不正确,应该是printf("%s\n", aPtr[i]);

答案 1 :(得分:2)

我看到的问题:

  1. 您没有为aPtr[i]分配足够的内存。

    aPtr[i]=(char *)malloc(sizeof(char));
    

    仅为一个char分配内存。拿绳子还不够。你需要这样的东西:

    int arraySize = 20; // Make it large enough
    aPtr[i] = malloc(arraySize); // No need to use sizeof(char).
                                 // It is always 1
    
  2. 确保在阅读字符串时,不要超出数组大小。而不是:

    fscanf(input,"%s",&aPtr[i]);
    

    使用:

    fscanf(input,"%19s", aPtr[i]);
    //                  ^^^ Remove the & operator. That is wrong.
    //            ^^^ Add size to prevent overflow.
    
  3. 您使用printf函数的错误参数。而不是:

    printf("%s\n",(aPtr+i));
    

    使用

    printf("%s\n", *(aPtr+i));
    //            ^^^ Missing pointer dereferencing operator
    

    printf("%s\n", aPtr[i]);
    

答案 2 :(得分:0)

关于你的问题的第一个评论是问题的核心     malloc(sizeof(char))实际上只是malloc(1)

你所做的是......

分配N个字符指针的数组

aPtr = (char **)malloc(sizeof(char *)*b); 

为列表中的每个指针分配一个字符

for(i=0;i<b;i++) {
  aPtr[i]=(char *)malloc(sizeof(char));
}

将未知长度的字符串复制到分配给列表中每个指针的内存中。

for(i = 0;i < b;i++){
  fscanf(input,"%s",&aPtr[i]);
}

分配给每个字符指针的内存可能与分配给其前一个内存的内存相近或相邻。后续写入可能会覆盖前面字符串的某些部分。在你的例子的情况下,在连续分配的内存块之间似乎存在足够的差距,只有“葡萄柚”条目足够长,明显被其邻居踩踏。

答案 3 :(得分:0)

你去:)(我试着在评论中解释)

int main() {

    FILE * pFile;
    char * buffer = NULL;
    size_t size = 0;
    ssize_t line_length;

    pFile = fopen("inpit.txt", "r");
    if (pFile != NULL) {
        int number_of_lines;
        fscanf(pFile, "%d", &number_of_lines);

        //create charcter pointers array to hold each line
        char* strings[number_of_lines];

        int i = -1;
        while ((line_length = getline(&buffer, &size, pFile)) != -1) {
            if (i != -1) { // skips first line because its number of lines (5)
                strings[i] = malloc(line_length * sizeof(char)); //allocate memory for the line
                sprintf(strings[i], "%s", buffer); //copy line from buffer to allocated space 
            }
            //incase file has more than it said
            if (i++ >= number_of_lines) { break; }
        }

        //Test print
        for (i = 0; i <= number_of_lines; i++) {
            printf("%s", strings[i]);
        }
        printf("\n");

        fclose(pFile);
        if (buffer) { free(buffer); }
    }
}