我是 C 的新手,在重置或清除指向结构的全局指针数组时遇到了一些问题。 我需要接收一个文件(或更多)并在两个周期内读取它的行。 在阅读它时,我需要创建一个符号表(基本上是标签),然后使用它来创建更多数据(将标签的位置导出到以十六进制值写入的文件)。
我遇到的问题是在读取两个文件时。第一个文件读取正常并且所有值都正确,但是当它尝试读取第二个文件时,即使我释放了它们,我创建的表(数组)中的值仍然存在。
我在头文件中声明了这个:(SIZE 为 30)
typedef struct symbol{
unsigned action :1;
unsigned external :1;
int address;
char label[SIZE];
unsigned data_flag :1;
} symbol ;
symbol *symbol_Table[SIZE] ;
添加新符号的示例:(这位于阅读功能中)
new_symbol = malloc(sizeof(symbol));
strcpy(new_symbol->label, temp);
new_symbol->external = 0;
new_symbol->address = DC - tok_count;
new_symbol->action = 0;
new_symbol->data_flag = 1;
add_symbol(new_symbol);
free(new_symbol);
添加函数,在不同的文件中:(UPDATE)
if(count == SIZE){
**/*realloc the array size, increase it*/**
}
if(count < SIZE){
symbol_Table[count] = malloc(sizeof(symbol));
symbol_Table[count]->action = new_symbol->action;
symbol_Table[count]->external = new_symbol->external;
symbol_Table[count]->address = new_symbol->address;
strcpy(symbol_Table[count]->label, new_symbol->label);
symbol_Table[count]->data_flag = new_symbol->data_flag;
/*printf("count: %d\n", count);*/
return ++count;
}
return count;
并在读取循环结束时释放符号:(UPDATE)
int i;
for(i = 0; i < count ; i++){
free(symbol_Table[i]);
symbol_Table[i] = NULL;
}
这是第一个文件的第一个循环后的正确输出:
action: no | extern: yes | address: 0 | label L3 | data: no
action: no | extern: yes | address: 0 | label W | data: no
action: yes | extern: no | address: 100 | label MAIN | data: no
action: yes | extern: no | address: 106 | label LOOP | data: no
action: yes | extern: no | address: 119 | label END | data: no
action: no | extern: no | address: 0 | label STR | data: yes
action: no | extern: no | address: 7 | label LENGTH | data: yes
action: no | extern: no | address: 10 | label K | data: yes
以及第二个文件的第一个循环后的错误输出:(UPDATE)
action: yes | extern: no | address: 100 | label MAIN | data: yes
action: no | extern: yes | address: 0 | label W | data: yes
action: yes | extern: no | address: 108 | label LOOP | data: yes
action: no | extern: no | address: 0 | label STR | data: yes
action: no | extern: no | address: 3 | label K | data: yes
应该是:
action: yes | extern: no | address: 100 | label MAIN | data: no
action: no | extern: yes | address: 0 | label W | data: no
action: yes | extern: no | address: 108 | label LOOP | data: no
action: no | extern: no | address: 0 | label STR | data: yes
action: no | extern: no | address: 3 | label K | data: yes
几个问题:
- 有没有办法在我使用后清理列表?然后为新值重用相同的列表?并避免内存泄漏。
- 这个关于数组的想法是否只是浪费空间,我应该尝试使用链表吗?我担心我将不得不重新编写整个项目,而且时间不在我身边..
(更新后)
- 当到达末尾时,如何重新分配更多内存以增加数组的大小?
如果我误用了一个术语,我深表歉意,我正在用另一种语言学习 C。
最佳答案
即使您正在释放结构,您的数据也不会立即被覆盖,因为不需要堆分配器;它只是记下您释放的空间可用。您应该更进一步,在释放数组后将数组的每个索引设置为 NULL。这实际上会将它们从您的阵列中移除。
现在,我在使用数组时会很谨慎。您已指定大小,但并未在添加函数中强制执行。
如果您使用 malloc 将数组交换为使用动态内存,并且稍后在程序中达到大小限制,则可以使用 realloc
分配更多空间(这基本上允许您实现 ArrayList 而不会影响程序的其余部分的实现)。
要最初为您的数组分配空间,请尝试:
symbol **symbol_Table = (symbol *) malloc(sizeof(symbol *) * SIZE);
注意: malloc 只能从方法内部调用。所以,在你的文件的顶部,你可以声明你的变量:
symbol **symbol_Table;
然后,在使用它之前,你应该在你的 main()
中定义它方法:
symbol_Table = (symbol **) malloc(sizeof(symbol **) * SIZE);
注意 malloc 语句中的符号 - 你需要乘以
具有符号指针大小的数组,因为 malloc 占用要分配的字节数。 sizeof(symbol *)
给你一个 symbol
的大小指针。
另外:为了使用realloc,初始分配symbol_Table
应该是 malloc/calloc/realloc 返回的东西,或者 NULL。
如果您只是想将重新分配弹出到您的 if 语句中,请尝试:
static size_t current_size = SIZE;
if(count == current_size) {
current_size = current_size << 1;
symbol_Table = (symbol *)realloc(symbol_table, sizeof(symbol *) * current_size);
}
if(count < current_size) {
// ... the rest of the code continues here
关于 current_size << 1
的一点是左移位 - 它有效地乘以 current_size
两个。
静态变量在函数调用之间保留它们的值。因此,如果我在一次调用该函数时更改它,那么在下次调用该函数时,该变量将具有我在上一次调用中设置的值。使用静态变量的原因是,如果增加数组的大小,则应在调用之间保存 current_size 的值,并且必须将数组的大小存储在某处。存储它的最佳位置是在数组的实际大小很重要的一个函数中 - 唯一会被放大的地方。不过,全局变量也同样有效。
在最后释放符号表:
int i;
for(i = 0; i < count ; i++){
if(symbol_Table[i] != NULL) // Important - we cannot free NULL
{
free(symbol_Table[i]);
symbol_Table[i] = NULL;
}
}
count = 0; // Important - if we are deleting everything in the array, we
// need to make sure we reset the count for our next delete
// operation
关于c - 重置/清除指向结构的全局指针数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42957370/