使用“realloc"的问题在 C [英] Problems using "realloc" in C

查看:67
本文介绍了使用“realloc"的问题在 C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有从套接字接收字符串数据的代码,该套接字在第一次迭代时崩溃:

I have code receiving string data from a socket which crashes on the first iteration:

int size_data = 1024*sizeof(char);              
char *data = malloc(size_data);
char *data_aux;
int br_aux=0;
int *nptr;

memset(&data[0], 0, size_data);
int br = recv(sockdata, data, size_data, 0);
data_aux = malloc(br);
while (br>0) {
  br_aux = br_aux + br;
  strcat(data_aux, data);
  br = recv(sockdata,data, size_data, 0);
  if (br > 0) {
    nptr = (int *) realloc(data_aux, br+br_aux);
  }
}
free(data);
printf("%s", data_aux);
free(data_aux);

没有那么复杂,但是我得到了一个错误:

Nothing so complicated, but however I get an error:

* glibc 检测到 ./clientFTP: free(): 下一个大小无效(正常):0x00000000061d6420 **======== 回溯:=========/lib64/libc.so.6[0x366be7247f]/lib64/libc.so.6(cfree+0x4b)[0x366be728db] ./clientFTP[0x401e39]/lib64/libc.so.6(__libc_start_main+0xf4)[0x366be1d9b4]./clientFTP[0x400b89]========内存映射:======== 00400000-00403000 r-xp 00000000 fd:00 5396214/home/alumno/FTP/clientFTP00602000-00603000 rw-p 00002000 fd:00 5396214
/home/alumno/FTP/clientFTP 061d6000-061f7000 rw-p 061d6000 00:00 0
[堆] 366ba00000-366ba1c000 r-xp 00000000 fd:00 1994999
/lib64/ld-2.5.so 366bc1c000-366bc1d000 r--p 0001c000 fd:00 1994999
/lib64/ld-2.5.so 366bc1d000-366bc1e000 rw-p 0001d000 fd:00 1994999
/lib64/ld-2.5.so 366be00000-366bf4e000 r-xp 00000000 fd:00 1995001
/lib64/libc-2.5.so 366bf4e000-366c14e000 ---p 0014e000 fd:00 1995001
/lib64/libc-2.5.so 366c14e000-366c152000 r--p 0014e000 fd:00 1995001
/lib64/libc-2.5.so 366c152000-366c153000 rw-p 00152000 fd:00 1995001
/lib64/libc-2.5.so 366c153000-366c158000 rw-p 366c153000 00:00 03672200000-367220d000 r-xp 00000000 fd:00 1995011
/lib64/libgcc_s-4.1.2-20080825.so.1 367220d000-367240d000 ---p0000d000 fd:00 1995011
/lib64/libgcc_s-4.1.2-20080825.so.1 367240d000-367240e000 rw-p0000d000 fd:00 1995011
/lib64/libgcc_s-4.1.2-20080825.so.1 2b5cdf8d9000-2b5cdf8dd000 rw-p2b5cdf8d9000 00:00 0 2b5cdf8f6000-2b5cdf8f7000 rw-p 2b5cdf8f600000:00 0 7fffae47e000-7fffae493000 rw-p 7ffffffe9000 00:00 0
[堆栈] 7fffae5fc000-7fffae600000 r-xp 7fffae5fc000 00:00 0
[vdso] ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0
[vsyscall] 中止

* glibc detected ./clientFTP: free(): invalid next size (normal): 0x00000000061d6420 ** ======= Backtrace: ========= /lib64/libc.so.6[0x366be7247f] /lib64/libc.so.6(cfree+0x4b)[0x366be728db] ./clientFTP[0x401e39] /lib64/libc.so.6(__libc_start_main+0xf4)[0x366be1d9b4] ./clientFTP[0x400b89] ======= Memory map: ======== 00400000-00403000 r-xp 00000000 fd:00 5396214 /home/alumno/FTP/clientFTP 00602000-00603000 rw-p 00002000 fd:00 5396214
/home/alumno/FTP/clientFTP 061d6000-061f7000 rw-p 061d6000 00:00 0
[heap] 366ba00000-366ba1c000 r-xp 00000000 fd:00 1994999
/lib64/ld-2.5.so 366bc1c000-366bc1d000 r--p 0001c000 fd:00 1994999
/lib64/ld-2.5.so 366bc1d000-366bc1e000 rw-p 0001d000 fd:00 1994999
/lib64/ld-2.5.so 366be00000-366bf4e000 r-xp 00000000 fd:00 1995001
/lib64/libc-2.5.so 366bf4e000-366c14e000 ---p 0014e000 fd:00 1995001
/lib64/libc-2.5.so 366c14e000-366c152000 r--p 0014e000 fd:00 1995001
/lib64/libc-2.5.so 366c152000-366c153000 rw-p 00152000 fd:00 1995001
/lib64/libc-2.5.so 366c153000-366c158000 rw-p 366c153000 00:00 0 3672200000-367220d000 r-xp 00000000 fd:00 1995011
/lib64/libgcc_s-4.1.2-20080825.so.1 367220d000-367240d000 ---p 0000d000 fd:00 1995011
/lib64/libgcc_s-4.1.2-20080825.so.1 367240d000-367240e000 rw-p 0000d000 fd:00 1995011
/lib64/libgcc_s-4.1.2-20080825.so.1 2b5cdf8d9000-2b5cdf8dd000 rw-p 2b5cdf8d9000 00:00 0 2b5cdf8f6000-2b5cdf8f7000 rw-p 2b5cdf8f6000 00:00 0 7fffae47e000-7fffae493000 rw-p 7ffffffe9000 00:00 0
[stack] 7fffae5fc000-7fffae600000 r-xp 7fffae5fc000 00:00 0
[vdso] ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0
[vsyscall] Aborted

推荐答案

有两个不同的问题.

一、线

nptr = (int *)realloc(data_aux,(br+br_aux));

做了三件事:

  1. 它尝试分配 br + br_aux 字节.
  2. 它可能会释放data_aux指向的内存.
  3. 它将nptr 指向新分配的内存地址.
  1. It tries to allocate br + br_aux bytes.
  2. It may release the memory that data_aux points to.
  3. It points nptr to the address of the newly-allocated memory.

但是代码继续使用data_aux,就好像它仍然指向新的内存一样.

But the code continues to use data_aux as if it still points to the new memory.

其次,由于 recv() 返回接收到的字节数,您应该使用该信息将数据附加到缓冲区:

Second, since recv() returns the number of bytes that were received, you should use that information to append data to the buffer:

while (br > 0) {
  memcpy(data_aux + br_aux, data, br);
  br_aux += br;
  br = recv(sockdata, data, size_data, 0);
  if (br > 0) {
    nptr = (int *) realloc(data_aux, br + br_aux);
    if (nptr == NULL) {
      // ERROR
    }
    data_aux = nptr;
  }
}

recv() 与任何字符串操作(如 strcat())结合的问题在于 recv() 可以返回二进制数据.如果该数据恰好包含零字节,则字符串函数将假定它是数据的结尾,并以您既不期望也不想要的方式运行.

The problem with recv() in combination with any of the string operations (like strcat()) is that recv() can return binary data. If that data happens to contain a zero byte, the string functions will assume it's the end of the data and behave in ways you neither expect nor want.

实际上还有第三个问题,那就是没有检查返回值是否有错误.总是检查错误,而不是假设内存有效,或者socked通信已经成功.

There's actually a third problem, which is that none of the return values is checked for errors. Always check for errors instead of assuming that memory is valid, or that socked communication has succeeded.

这篇关于使用“realloc"的问题在 C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆