【问题标题】:Malloc'ing pointer-to-pointer member of structMalloc'ing struct 的指针到指针成员
【发布时间】:2015-05-11 05:44:43
【问题描述】:

我正在尝试使用一个结构来保存指向数据块的指针,我有时会在文件更新时更改该指针,其想法是释放旧数据块,分配一个合适大小的新数据块,然后分配指向结构中指针的指针指向malloc返回的指针,这就是我认为我应该这样做的方式。但它会出现故障。事实上,在我为制作这个测试程序而缩减的更大程序中,它不是段错误,而是在 malloc 之后写入 stdout 什么都不做(之后在程序中的任何地方)。我想我是在 stdout FD 上写的,原因是当我将指针设置为 malloc()ed 返回值时,我错误地使用了指针。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>
#include <inttypes.h>

struct mystruct {
    int offset;
    int ** d;
};

int filecheck (struct mystruct *g, int * count) {
    int v, size = 0;
    FILE *f = fopen("/home/pi/schedule/default", "rb");
    if (f == NULL) { 
        return 0; 
    } 
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, 0, SEEK_SET);
    int schedsize = sizeof(int);
    int elementcount = size / schedsize;
//  free(*(g->d));
//  seg fault next line
    if ((*(g->d) = malloc(size))==NULL) return 0; 
    if (elementcount != fread(*(g->d), schedsize, elementcount, f)) { 
        free(*(g->d));
        return 0;
    } 
    fclose(f);
    *count = elementcount;  
    return 1;
}

void setp (struct mystruct *g) {
//  if uncommented, seg fault here
//  *(g->d) = NULL;
}

int main (){
    struct mystruct g;
    setp(&g);
    int i, count = 0;
    if (filecheck(&g, &count)==0) {
        printf("Returned 0\n");
        return 0;
    }
    while (1) {
        printf("%d\n", (*(g.d))[i]);
        sleep(1);
    }
    return 0;

}

为方便起见,我最初想在setp() 中将mystruct.d 设置为NULL,但即使注释掉代码仍然失败,所以我知道它完全错误。也许我不需要使用指向指针的指针,但在我看来我需要。

编辑:根据答案修改,可以吗?

struct mystruct {
    int offset;
    int * d;
};

int filecheck (struct mystruct *g, int * count) {
    int v, size = 0;
    FILE *f = fopen("/home/pi/schedule/default", "rb");
    if (f == NULL) { 
        return 0; 
    } 
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, 0, SEEK_SET);
    int schedsize = sizeof(int);
    int elementcount = size / schedsize;
    free (g->d);
    if ((g->d = malloc(size))==NULL) return 0; 
    if (elementcount != fread(g->d, schedsize, elementcount, f)) { 
        free(g->d);
        return 0;
    } 
    fclose(f);
    *count = elementcount;  
    return 1;
}

void setp (struct mystruct *g) {
    g->d = NULL;
}

int main (){
    struct mystruct g;
    setp(&g);
    int i, count = 0;
    if (filecheck(&g, &count)==0) {
        printf("Returned 0\n");
        return 0;
    }
    while (1) {
        for (i=0;i<count;i++) {
            printf("%d %d \n", *((g.d)+i), g.d[i]);
        }
        sleep(1);
    }
    return 0;

}

这似乎有效,但它是正确的,还是我写了一些我不应该再用这个写的内存?

【问题讨论】:

    标签: c pointers struct malloc dynamic-memory-allocation


    【解决方案1】:

    在使用它们之前,您需要为所有指针元素分配内存。

    这里,d 是一个指向指针的指针,首先你需要为d 本身分配内存,然后你应该继续解引用d(使用*d)。

    例如,要么

    void setp (struct mystruct *g) { 
    
     g->d = NULL;   // no need to derererence d here, but later need to allocate
    }
    

    或者,(为了更好

    void setp (struct mystruct *g) {
    
     g->d = malloc(32 * sizeof (int *));  // d is allocated
     g->d[i] = malloc(16 * sizeof (int));   // or g->d[i] = NULL; or *(g->d) = NULL;
    }
    

    应该可以正常工作。

    另外,main() 的推荐签名是int main(void)

    【讨论】:

    • 好的,非常感谢。 g->d 必须有多大?不确定我是否看对了,但我的看法是 g->d 只持有一个指针,指向从位置 *(g->d) 开始的较大内存块的开始。这是正确的还是我需要 g->d 和 *(g->d) 的大小相同?
    • @Pete 也许你是决定这一点的最佳人选。 :-) 你可以采取自下而上的方法来解决这个问题。 d[i] 的许多元素将在那里,您需要分配给 d(number * sizeof(int *)) 内存量。
    • 嗯,我一直看到这个,我需要为 ptr 分配一个 ptr 的事实是一个 PITA,我只想要一块内存,因为我实际上会通过增加指针来使用它.我真的需要 ** 还是 * 就足够了?我读到的几件事表明我需要**。根据上面的代码,我会将一个文件读入其中,而不是像我在此测试代码中所做的那样将其实际寻址为数组。
    • @Pete 我没有检查你的代码逻辑,但根据你的评论,一个简单的指针就足够了。 :-)
    • 感谢 Sourav,已在原始问题中添加了新代码(在第二个代码块中),你能说这是否可以?它似乎运行良好。
    猜你喜欢
    • 1970-01-01
    • 2021-12-03
    • 2018-03-24
    • 2023-03-12
    • 1970-01-01
    • 2015-02-19
    • 2012-05-06
    • 2013-05-02
    • 1970-01-01
    相关资源
    最近更新 更多