struct指向同一个内存地址产生不同的数据?

时间:2016-08-15 16:07:26

标签: c pointers struct malloc heap

我有这个简单的代码来读取文件的行并将它们存储在结构中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>    

struct filedata {
    char **items;
    int lines;
};    

struct filedata *read_file(char *filename) {
    FILE* file = fopen(filename, "r");    

    if (file == NULL) {
        printf("Can't read %s \n", filename);
        exit(1);
    }    

    char rbuff;     

    int nlines = 0; // amount of lines
    int chr = 0; // character count
    int maxlen = 0; // max line length (to create optimal buffer)
    int minlen = 2; // min line length (ignores empty lines with just \n, etc)    

    while ((rbuff = fgetc(file) - 0) != EOF) {
        if (rbuff == '\n') {
            if (chr > maxlen) {
                maxlen = chr + 1;
            }    

            if (chr > minlen) {
                nlines++;
            }    

            chr = 0;
        }    

        else {
            chr++;
        }
    }    

    struct filedata *rdata = malloc(sizeof(struct filedata));
    rdata->lines = nlines;    

    printf("lines: %d\nmax string len: %d\n\n", nlines, maxlen);
    rewind(file);    

    char *list[nlines];    

    int buffsize = maxlen * sizeof(char);
    char buff[buffsize];    

    int i = 0;
    while (fgets(buff, buffsize, file)) {
        if (strlen(buff) > minlen) {
            list[i] = malloc(strlen(buff) * sizeof(char) + 1);
            strcpy(list[i], buff);
            i++;
        }
    }    

    rdata->items = (char **)list;
    fclose(file);    

    int c = 0;
    for (c; c < rdata->lines; c++) {
        printf("line %d: %s\n", c + 1, rdata->items[c]);
    }    

    printf("\n");
    return rdata;
}    

int main(void) {
    char fname[] = "test.txt";
    struct filedata *ptr = read_file(fname);    

    int c = 0;
    for (c; c < ptr->lines; c++) {
        printf("line %d: %s\n", c + 1, ptr->items[c]);
    }    

    return 0;
}

这是我运行时的输出:

lines: 2
max string len: 6

line 1: hello
line 2: world

line 1: hello
line 2: H��

出于某种原因,当它到达ptr->项目中的第二个索引时,它会输出乱码输出。但是,如果我在那里抛出一些printf()来显示指针地址,它们就完全相同了。

Valgrind在第二次迭代char数组时也打印出来:

==3777== Invalid read of size 8
==3777==    at 0x400AB3: main (test.c:81)
==3777==  Address 0xfff000540 is on thread 1's stack
==3777==  240 bytes below stack pointer

但在这种情况下,这确实没有给我任何线索。

如果重要的话,我正在使用gcc 4.9.4和glibc-2.24。

1 个答案:

答案 0 :(得分:0)

变量listread_file的本地变量,但您在list中存储了指向rdata->items的指针。当read_file返回时,rdata->items是一个悬空指针,访问它是未定义的行为。