簡體   English   中英

結構指針指向相同的內存地址產生不同的數據?

[英]struct pointers to same memory address producing different data?

我有以下簡單代碼來讀取文件的行並將其存儲在結構中:

#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-> items中的第二個索引時,它會輸出亂碼。 但是,如果我在其中扔一些printf()來顯示指針地址,它們是完全一樣的。

當第二次遍歷char數組時,Valgrind也將打印此內容:

==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。

list是一個非靜態的局部變量,退出范圍(在本例中從read_file返回)后使用它會調用未定義的行為,因為它會在退出范圍時消失。 動態分配(通常在堆上),例如

char **list = malloc(sizeof(char*) * nlines);

添加代碼以檢查malloc()是否成功將使您的代碼更好。

變量listread_file本地變量,但是您在rdata->items存儲了指向list的指針。 read_file返回時, rdata->items是一個懸空指針,對其進行訪問是未定義的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM