难以在动态分配的嵌套结构中设置指针

发布于 2025-01-30 17:43:28 字数 4492 浏览 3 评论 0原文

在这个事情上呆了一段时间。我正在编写一个C程序,该程序将CSV文件解析为嵌套结构。当我将**传递到add_field函数中时,我能够获取所有指针,直到到达字段数组的字段[(* f)-1]指针。这总是返回零,我不知道原因。任何帮助将不胜感激。谢谢。

对不起,巨大的代码转储,但我不想遗漏任何东西。我一直在每个Alloc之后检查NULL,但还没有将它们整合到此重写中(我正在观看逐步介绍的变量值)。

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

/* Inline function for handling errors during memory allocation */
extern int errno;
#ifndef error
#define ERROR static inline void *
__attribute((always_inline)) ERROR error() {
    printf("%d\n", errno);
    printf("%s", strerror(errno));
    exit(EXIT_FAILURE);
}
#endif
/* ------------------------------------------------------------ */

#define MAX_BUFFER_SIZE 100


typedef struct data_field {

        char * data;
        size_t fldsize;

    } FIELD;

typedef struct data_set {

        int field_count;
        size_t setsize;
        FIELD ** field;

    } SET;

typedef struct csv_file {

        char * filename;
        int set_count;
        size_t filesize;
        SET ** set;

    } CSV;

CSV * alloc_csv();
void add_set(CSV ** fp, const int * setcnt);
void add_field(SET **sp, char *buffer, const int *f);
char * file_read(char * file_name);



int main()
{
    int b = 0;
    ulong bufcnt = 0;
    int fldcnt = 0;
    int setcnt = 0;
    int bmax = 100;

    char tok1 = '\n';
    char tok2 =  ',';
    char * buffer;
    char * stream;

    stream = file_read("/home/jonathon/Documents/programming/personal/csv/data_files/MOCK_DATA.csv");

    CSV * file = {0};
    void * filetmp = malloc(sizeof(CSV));
    file = filetmp;
    file->set_count = 0;

    void * arrtmp = calloc(1, sizeof(SET *));
    file->set = (SET **)arrtmp;

    void * settmp = calloc(1, sizeof(SET));
    file->set[0] = (SET *)settmp;

    setcnt++;

    void * buftmp = malloc(sizeof(char) * MAX_BUFFER_SIZE);
    buffer = buftmp;

    // read stream until end of field
    buftmp = malloc(sizeof(char) * MAX_BUFFER_SIZE);
    buffer = buftmp;
    for (int c = 0; stream[c] != '\0'; c++)
    {
        if (b >= bmax)
        {
            buftmp = realloc(buffer, sizeof(char) * (MAX_BUFFER_SIZE + bmax));
            buffer = buftmp;
        }

        switch (stream[c])
        {
            case 10:
                buffer[b] == '\0';
                b = 0;
                
                break;
            case 44:
                buffer[b] == '\0';
                add_field(&file->set[setcnt - 1], buffer, &fldcnt);
                fldcnt++;

                b = 0;
                break;
            default:
                buffer[b] = stream[c];
                b++;
                
        }
    }
}

void add_field(SET ** sp, char * buffer, const int * f)
{
    ulong buflen = strlen(buffer + 1);

    if ((*f) == 0)
    {
        (*sp)->field = (FIELD **)calloc(1, sizeof(FIELD *));
    }
    else
    {
        (*sp)->field = (FIELD **)realloc((*sp)->field, sizeof(FIELD *) * ((*f) + 1));
    }

    (*sp)->field[(*f) - 1] = (FIELD *)calloc(1, sizeof(FIELD));

    (*sp)->field[(*f) - 1]->data = (char *)calloc(buflen, sizeof(char));
    memcpy((*sp)->field[(*f) - 1]->data, buffer, buflen * sizeof(char));
}

void free_csv(CSV ** fp, const int * setcnt, const int * fldcnt)
{
    for (int i = 0; i < * setcnt; i++)
    {
        for (int j = 0; j < * fldcnt; j++)
        {
            free((* fp)->set[i]->field[j]->data);
            free((* fp)->set[i]->field[j]);
        }
        free((* fp)->set[i]->field);
        free((* fp)->set[i]);
    }
    free((* fp)->set);
    free(* fp);
}

char *file_read(char* file_name)
{
    FILE *fp = fopen(file_name, "rb");
    size_t file_size;

    char* file_buffer = NULL;

    if (!fp)
    {
        perror("Error: ");
        exit(EXIT_FAILURE);
    }
    else
    {
//              Seek to end of file to get file file_size
        fseek(fp, 0, SEEK_END);
        file_size = ftell(fp);
        file_buffer = (char *)calloc(file_size, sizeof(char));      // Allocate buffer file_size
        if (!file_buffer)
        {
            perror("Error: ");
            exit(EXIT_FAILURE);
        }

//              Seek to beginning of file to read from start.
        fseek(fp, 0, SEEK_SET);
        if (fread(file_buffer, file_size, 1, fp) != 1)        // Read into buffer
        {
            perror("Error: ");
            exit(EXIT_FAILURE);
        }

        fclose(fp);
    }

    return file_buffer;
}```

Been at this thing for awhile. I'm writing a C program that parses a csv file into a nested struct. When I pass the ** to the struct into the add_field function, I am able to get all of the pointers until I get to the field[(* f) - 1] pointer of the field array. That always returns NULL and I cannot figure out why. Any help would be greatly appreciated. Thank you.

Sorry for the huge code dump but I didn't want to leave anything out. I've been checking for null after every alloc but haven't incorporated them yet in this rewrite (I’m watching variable values with step in on clion).

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

/* Inline function for handling errors during memory allocation */
extern int errno;
#ifndef error
#define ERROR static inline void *
__attribute((always_inline)) ERROR error() {
    printf("%d\n", errno);
    printf("%s", strerror(errno));
    exit(EXIT_FAILURE);
}
#endif
/* ------------------------------------------------------------ */

#define MAX_BUFFER_SIZE 100


typedef struct data_field {

        char * data;
        size_t fldsize;

    } FIELD;

typedef struct data_set {

        int field_count;
        size_t setsize;
        FIELD ** field;

    } SET;

typedef struct csv_file {

        char * filename;
        int set_count;
        size_t filesize;
        SET ** set;

    } CSV;

CSV * alloc_csv();
void add_set(CSV ** fp, const int * setcnt);
void add_field(SET **sp, char *buffer, const int *f);
char * file_read(char * file_name);



int main()
{
    int b = 0;
    ulong bufcnt = 0;
    int fldcnt = 0;
    int setcnt = 0;
    int bmax = 100;

    char tok1 = '\n';
    char tok2 =  ',';
    char * buffer;
    char * stream;

    stream = file_read("/home/jonathon/Documents/programming/personal/csv/data_files/MOCK_DATA.csv");

    CSV * file = {0};
    void * filetmp = malloc(sizeof(CSV));
    file = filetmp;
    file->set_count = 0;

    void * arrtmp = calloc(1, sizeof(SET *));
    file->set = (SET **)arrtmp;

    void * settmp = calloc(1, sizeof(SET));
    file->set[0] = (SET *)settmp;

    setcnt++;

    void * buftmp = malloc(sizeof(char) * MAX_BUFFER_SIZE);
    buffer = buftmp;

    // read stream until end of field
    buftmp = malloc(sizeof(char) * MAX_BUFFER_SIZE);
    buffer = buftmp;
    for (int c = 0; stream[c] != '\0'; c++)
    {
        if (b >= bmax)
        {
            buftmp = realloc(buffer, sizeof(char) * (MAX_BUFFER_SIZE + bmax));
            buffer = buftmp;
        }

        switch (stream[c])
        {
            case 10:
                buffer[b] == '\0';
                b = 0;
                
                break;
            case 44:
                buffer[b] == '\0';
                add_field(&file->set[setcnt - 1], buffer, &fldcnt);
                fldcnt++;

                b = 0;
                break;
            default:
                buffer[b] = stream[c];
                b++;
                
        }
    }
}

void add_field(SET ** sp, char * buffer, const int * f)
{
    ulong buflen = strlen(buffer + 1);

    if ((*f) == 0)
    {
        (*sp)->field = (FIELD **)calloc(1, sizeof(FIELD *));
    }
    else
    {
        (*sp)->field = (FIELD **)realloc((*sp)->field, sizeof(FIELD *) * ((*f) + 1));
    }

    (*sp)->field[(*f) - 1] = (FIELD *)calloc(1, sizeof(FIELD));

    (*sp)->field[(*f) - 1]->data = (char *)calloc(buflen, sizeof(char));
    memcpy((*sp)->field[(*f) - 1]->data, buffer, buflen * sizeof(char));
}

void free_csv(CSV ** fp, const int * setcnt, const int * fldcnt)
{
    for (int i = 0; i < * setcnt; i++)
    {
        for (int j = 0; j < * fldcnt; j++)
        {
            free((* fp)->set[i]->field[j]->data);
            free((* fp)->set[i]->field[j]);
        }
        free((* fp)->set[i]->field);
        free((* fp)->set[i]);
    }
    free((* fp)->set);
    free(* fp);
}

char *file_read(char* file_name)
{
    FILE *fp = fopen(file_name, "rb");
    size_t file_size;

    char* file_buffer = NULL;

    if (!fp)
    {
        perror("Error: ");
        exit(EXIT_FAILURE);
    }
    else
    {
//              Seek to end of file to get file file_size
        fseek(fp, 0, SEEK_END);
        file_size = ftell(fp);
        file_buffer = (char *)calloc(file_size, sizeof(char));      // Allocate buffer file_size
        if (!file_buffer)
        {
            perror("Error: ");
            exit(EXIT_FAILURE);
        }

//              Seek to beginning of file to read from start.
        fseek(fp, 0, SEEK_SET);
        if (fread(file_buffer, file_size, 1, fp) != 1)        // Read into buffer
        {
            perror("Error: ");
            exit(EXIT_FAILURE);
        }

        fclose(fp);
    }

    return file_buffer;
}```

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文