难以在动态分配的嵌套结构中设置指针
在这个事情上呆了一段时间。我正在编写一个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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论