我是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);
添加功能,在另一个文件中:(更新)
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.
答案 0 :(得分:1)
即使你正在释放你的结构,你的数据也不会立即被覆盖,因为堆分配器并不是必需的;它只是记下你释放的空间是可用的。您应该更进一步,并在释放它们之后将数组的每个索引设置为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
乘以2。
静态变量在函数调用之间保留其值。因此,如果我在调用函数一次时更改它,下次调用函数时,变量将具有我在上一次调用中设置的值。静态变量的原因是,如果增加数组的大小,则必须在调用之间保存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
答案 1 :(得分:0)
你的问题是(IMO)SIZE
是一个常数。如果你使它变量,你可以在需要时调整符号表的大小。
最干净的方法是将指针数组与大小一起存储在某个包络结构中,如:
struct symbol{
unsigned action :1;
unsigned external :1;
unsigned data_flag :1;
int address;
char label[SIZE];
} symbol ;
struct symtab{
unsigned size;
unsigned used;
struct symbol **table; /* used as an array of pointers */
};
/* global: for fun */
struct symtab thetab = {0,0,NULL};
int resize_the_thing(struct symtab *sp, unsigned new_size)
{
struct symbol **newtable;
/* Note: realloc takes care of copying, too ...*/
newtable = realloc (sp->table, new_size * sizeof sp->table[0]);
if (!newtable) { /* handle error */
return -1;
}
sp->table = newtable;
/* TODO: you need to check the case new_size < size here, too */
sp->size = new_size;
return 0; /* no_error */
}
/* typical usage: */
if (thetab.used >= thetab.size && resize_the_thing( &thetab, 12345)) {
/* report error */
}
thetab.table[thetab.used++] = new_symbol(...);