c - 重置/清除指向结构的全局指针数组

标签 c arrays struct

我是 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

几个问题:

  1. 有没有办法在我使用后清理列表?然后为新值重用相同的列表?并避免内存泄漏。
  2. 这个关于数组的想法是否只是浪费空间,我应该尝试使用链表吗?我担心我将不得不重新编写整个项目,而且时间不在我身边..

(更新后)

  1. 当到达末尾时,如何重新分配更多内存以增加数组的大小?

如果我误用了一个术语,我深表歉意,我正在用另一种语言学习 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/

相关文章:

c# - 将结构数组从 C# 传递到 C++ DLL

c - 使用 pthreads 在 C 中进行矩阵乘法,可能存在数组访问问题

c++ - MATLAB编码器: sparse matrix

c++ - std::array 的嵌套聚合初始化

javascript - 基本 For 循环逻辑对我来说没有意义

c - C中的fread和fwrite如何区分不同的数据(类型)?

c - C 中矩阵可以在结构体中工作吗?

c - 案例循环有问题

c - 相似程序中的位移不同结果

Ruby Arrays - 求对角线的总和