c - 使用 realloc() 将数组的大小加倍

标签 c memory realloc

以下是我的程序的节选。

void insert(int *pq,int key){
      if(MS==N){
           pq=(int*)realloc(pq,sizeof(int)*MS*2);
           MS*=2;
      }
      pq[++N]=INT_MIN;
      increase_key(pq,N,key); 
}

int* priority_queue(){
     int *heap=(int*)malloc(sizeof(int)*10);
     MS=10;
     return heap;
} 

在插入函数中重新分配内存时出现此错误。我想在数组完全填满后将其大小加倍。

(gdb) n
46             pq=(int*)realloc(pq,sizeof(int)*MS*2);
(gdb) n
*** Error in `/home/akhileshydv/Documents/Cprog/a.out': realloc(): invalid next size: 0x0000000000602010 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7ffff7a847e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x834aa)[0x7ffff7a904aa]
/lib/x86_64-linux-gnu/libc.so.6(+0x85ba9)[0x7ffff7a92ba9]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x22f)[0x7ffff7a918ef]
/home/akhileshydv/Documents/Cprog/a.out[0x4007d5]
/home/akhileshydv/Documents/Cprog/a.out[0x4005e8]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7ffff7a2d830]
/home/akhileshydv/Documents/Cprog/a.out[0x4004e9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:09 3414051                            /home/akhileshydv/Documents/Cprog/a.out
00600000-00601000 r--p 00000000 08:09 3414051                            /home/akhileshydv/Documents/Cprog/a.out
00601000-00602000 rw-p 00001000 08:09 3414051                            /home/akhileshydv/Documents/Cprog/a.out
00602000-00623000 rw-p 00000000 00:00 0                                  [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0 
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0 
7ffff77f7000-7ffff780d000 r-xp 00000000 08:09 3936807                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff780d000-7ffff7a0c000 ---p 00016000 08:09 3936807                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a0c000-7ffff7a0d000 rw-p 00015000 08:09 3936807                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a0d000-7ffff7bcd000 r-xp 00000000 08:09 3938830                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7bcd000-7ffff7dcd000 ---p 001c0000 08:09 3938830                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dcd000-7ffff7dd1000 r--p 001c0000 08:09 3938830                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd1000-7ffff7dd3000 rw-p 001c4000 08:09 3938830                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd3000-7ffff7dd7000 rw-p 00000000 00:00 0 
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:09 3938808                    /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7fdb000-7ffff7fde000 rw-p 00000000 00:00 0 
7ffff7ff5000-7ffff7ff8000 rw-p 00000000 00:00 0 
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0                          [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:09 3938808                    /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:09 3938808                    /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Program received signal SIGABRT, Aborted.
0x00007ffff7a42428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
54  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.

为什么我会收到这个错误?请提出任何解决方案。

编辑:我已按照评论部分的建议将“pq”变量设置为全局变量,但问题仍然存在。

void priority_queue(){
     pq=malloc(sizeof(int)*10);
     MS=10;
}

void insert(int key){
      if(MS==N){
           pq=realloc(pq,sizeof(int)*MS*2);
           MS*=2;
      }
      pq[++N]=INT_MIN;
      increase_key(N,key); 
}

最佳答案

几个问题:

  1. 您需要在 insert 函数中对 pq 进行额外的间接访问 - 如果您使用 realloc 更新值,那pq 的新值不会在调用 insert 的函数中更新。

  2. 切勿将 realloc 的结果直接分配给原始指针 - 如果 realloc 失败,它将返回 NULL,并且您最终会丢失对先前分配的内存的引用,从而导致内存泄漏。将结果分配给临时变量,检查临时变量以确保 realloc 成功,然后更新您的原始指针和大小变量。

  3. 如果您打算让 N 成为 *pq下一个可用元素的索引,那么您应该更新它作为 N++,而不是 ++N。如果您使用 ++N,则 N最后写入的元素 的索引(并且您跳过了元素 0,并且您冒着索引一个元素的风险超过数组中的最后一个元素)。根据 insert 函数的编写方式,您似乎打算让 N 代表 *pq 中的下一个可用元素,因此您应该将其更新为 N++

  4. 不要强制转换 malloc/calloc/realloc 的结果 - 如果您的编译器报错,那么您正在编译此代码作为 C++,而不是 C。如果您打算将此代码编译为作为 C++,那么您不应该在以下位置使用 malloc全部,而是 vector 或其他一些标准容器。如果您打算将此代码编译为 C,则不要对 mallocrealloc 进行强制转换,并仔细检查您的编译器设置。

把这些放在一起:

void insert(int **pq, int key){
      if(MS == N) {
           int *tmp = realloc(*pq, sizeof **pq * MS * 2); // sizeof **pq == sizeof (int)
           if (tmp)
           {
             *pq = tmp;
             MS *= 2;
           }
           else
           {
             // realloc failed, original buffer is still intact.  Handle
             // as appropriate.
           }
      }
      (*pq)[N++] = INT_MIN; // parens are required here
      increase_key(*pq, N, key); // assuming increase_key does not need to modify pq
}

你可以这样调用它:

int *q = malloc( sizeof *q * INITIAL_NUMBER_OF_ELEMENTS );
...
insert( &q, keyval );

关于c - 使用 realloc() 将数组的大小加倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46448653/

相关文章:

c - 比较 int 与 char 时,C 中的简单 'if' 语句未按预期执行

c++ - 获得余数的反面?

java - java中的数组实际上是顺序内存数据结构吗?或物理顺序?

c - 将元素添加到包含 char 指针的结构中

使用 Wifly Shield 和 arduino 创建客户端,并且 WiFly.begin() 失败

c - 计算每个像素8-邻接最大像素灰度值的最快方法

Java类与数组内存大小?

java - 为什么我不能在 eclipse.ini 中将 -Xmx 设置为 1024m?

c - realloc 后奇怪的字符

c - 为结构数组分配空间,Valgrind 无效读取