简体   繁体   English

分配结构的指针对指针成员

[英]Malloc'ing pointer-to-pointer member of struct

I'm trying to use a structure to hold a pointer to a data block that I change sometimes when a file is updated, the idea being to free the old data block, malloc a new one of the right size, and assign the pointer to pointer in the structure to the pointer returned by malloc, and this is how I thought I should do it. 我正在尝试使用一种结构来保存指向数据块的指针,该文件有时会在文件更新时更改,该想法是释放旧数据块,malloc正确大小的新块,并将指针分配给结构体中的指针指向malloc返回的指针,这就是我认为应该这样做的方式。 But it seg faults. 但这是错误。 In fact in the larger program that I pared down to make this test program, its not seg faulting but writing to stdout does nothing after the malloc (anywhere in the program after that). 实际上,在我缩减为该测试程序的较大程序中,它不是段错误,而是在malloc之后(向程序中的任何地方)写入stdout不会执行任何操作。 I guess I am writing over the stdout FD, the cause being that I am using the pointers incorrectly when I set the pointer to the malloc() ed return value. 我想我正在写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;

}

For convenience I want to set mystruct.d to NULL initially, in setp() , but even if thats comented out the code still fails, so I know its completely wrong. 为了方便起见,我想在mystruct.d setp()中将mystruct.d初始设置为NULL ,但是即使那没错,代码仍然会失败,所以我知道它是完全错误的。 Maybe I don't need to be using a pointer to pointer but it seems to me I do. 也许我不需要使用指向指针的指针,但是在我看来我确实需要。

EDIT: Modified as per answer, is this OK? 编辑:根据答案修改,可以吗?

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;

}

This seems to work but is it correct or am I writing over some part of memory I am not supposed to again with this? 这似乎可行,但这是正确的,还是我应该重写内存的某个部分,我不应该再对此进行处理?

You need to allocate memory to all the pointer elements before using them. 您需要在使用所有指针元素之前为其分配内存。

Here, d being a pointer to pointer, first you need to allocate memory for d itself, then you should go on for dereferencing d (using *d ). 在这里, d是指向指针的指针,首先需要为d本身分配内存,然后应该继续对d进行解引用(使用*d )。

For example, either 例如,

void setp (struct mystruct *g) { 

 g->d = NULL;   // no need to derererence d here, but later need to allocate
}

or, ( for better ) 或者,( 为了更好

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;
}

should work fine. 应该工作正常。

Also, the recommended siganture of main() is int main(void) . 另外, main()的推荐符号是int main(void)

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

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