(C) realloc数组按项修改数据
(C) realloc数组修改由项指向的数据 你好, 一个我想分享的奇怪的虫子;-)需要一些初步解释: 首先,我有一种类型的字符串(C) realloc数组按项修改数据,c,arrays,pointers,realloc,C,Arrays,Pointers,Realloc,(C) realloc数组修改由项指向的数据 你好, 一个我想分享的奇怪的虫子;-)需要一些初步解释: 首先,我有一种类型的字符串PString,它保存它们的大小(和一个散列值),后面是一个灵活的数组成员和字节。以下是构造函数的类型和种类(末尾的printfl语句是debug): [欢迎对此结构发表任何评论:我不确定是否正确操作。这是我第一次使用灵活数组成员,我找不到在分配结构中使用它们的示例。] 其次,这些pstring存储在一个字符串池中,这意味着一个实现为哈希表的集合。通常,冲突的“buc
PString
,它保存它们的大小(和一个散列值),后面是一个灵活的数组成员和字节。以下是构造函数的类型和种类(末尾的printfl语句是debug):
[欢迎对此结构发表任何评论:我不确定是否正确操作。这是我第一次使用灵活数组成员,我找不到在分配结构中使用它们的示例。]
其次,这些pstring存储在一个字符串池中,这意味着一个实现为哈希表的集合。通常,冲突的“bucket”(在散列和模之后)是单元格的普通链接列表,每个单元格都包含一个pstring指针和一个指向下一个单元格的指针。唯一特别的细节是单元本身存储在一个数组中,而不是在堆的任何位置分配[1]。希望情况清楚。以下是单元的定义:
typedef struct SCell {
PString * pstr;
struct SCell * next;
} Cell;
一切似乎都很好,包括对游泳池本身的一系列测试。现在,在测试pstring例程(搜索)时,我注意到一个字符串发生了变化。经过一些研究,我最终猜测问题与池增长有关,endly可以完全围绕单元格数组的增长来减少问题(因此,在将单元格重新分配到列表之前)。下面是围绕这一增长的调试打印行,其中show\u pool
例程的副本生成输出(仅显示字符串),输出本身:
static void pool_grow (StringPool * pool, uint n_new) {
...
// Grow arrays:
show_pool(pool); /////////////////////
pool->cells = realloc(pool->cells, pool->n_cells * sizeof(Cell));
check_mem(pool->cells);
show_pool(pool); ////////////////////
...
static void show_pool (StringPool * pool) {
if (pool->n == 0) {
printfl("{}");
return;
}
printf("pool : {\"%s\"", pool->cells[0].pstr->bytes);
PString * pstr;
uint i;
for (i = 1; i < pool->n; i++) {
pstr = pool->cells[i].pstr;
printf(", \"%s\"", pstr->bytes);
}
printl("}");
}
// output:
pool : {"", "abc", "b", "abcXXXabcXXX"}
pool : {"", "abc", "b", "abcXXXabcXXXI"}
static void pool\u grow(StringPool*pool,uint n\u new){
...
//增长阵列:
显示池(池)/////////////////////
池->单元=realloc(池->单元,池->n_单元*sizeof(单元));
检查内存(池->单元);
显示池(池)////////////////////
...
静态无效显示池(StringPool*池){
如果(池->n==0){
printfl(“{}”);
返回;
}
printf(“池:{\%s\”,池->单元格[0].pstr->字节);
PString*pstr;
uint i;
对于(i=1;in;i++){
pstr=pool->cells[i].pstr;
printf(“,\%s\”,pstr->字节);
}
printl(“}”);
}
//输出:
池:{”、“abc”、“b”、“abcXXXabcXXX”}
池:{”、“abc”、“b”、“abcXXXabcXXXI”}
如您所见,存储的最后一个字符串有一个额外的字节“I”。因为在此期间我只是调用realloc,我发现自己在进一步调试时遇到了一些障碍;而认真思考也无助于揭开这个谜团。(请注意,单元格只持有pstring指针,因此单元格数组的增长如何改变字符串字节?)还有,我被一个事实吓坏了,就是在神秘的“I”之后似乎有一个非常方便的NUL,因为printf在那里停了下来
多谢各位。
你能帮忙吗
[1] 在这里,使用字符串池没有特别的原因。我通常这样做是为了免费获得一个有序集或映射,以及引用的位置(唯一的开销是单元格数组必须在桶数组之外增长,但是可以通过预定尺寸来减少增长的数量)由于大小
不包括空终止符
mem[PSTRING_OFFSET + size] = NUL;
无效。所有其他问题都源于此。请删除所有杂乱的内容,只留下基本信息。您能帮忙吗?
这是您的问题吗?对于初学者来说,pool->cells=realloc(pool->cells,…)
是非常糟糕的realloc
用法。@netcoder当realloc()时,您指的是内存泄漏
返回NULL。“极端”有点强。如果意图是在realloc()时立即终止,这是一个不错的用法
失败,在这种情况下,泄漏只发生在程序退出所需的时间内。@netcoder:你能扩展吗?@qrdl:如果我没有发布相关的代码和解释,他们会被要求……就是这样,谢谢你ecatmur!我重写了一些代码进行清理,显然今天早上太早了,错过了+1。。。
mem[PSTRING_OFFSET + size] = NUL;