gpt4 book ai didi

c - 在 if 语句中无法重新分配内存

转载 作者:太空宇宙 更新时间:2023-11-04 06:38:23 24 4
gpt4 key购买 nike

尝试重新分配内存时,我在使用此代码时崩溃了:

//value of i is currently 4096
while((c = recv(sock, htmlbff + q, MAXDATASIZE, 0)) > 0)
{
if((i - q) < MAXDATASIZE)
{
i *= 2;
if(!(tmp = realloc(htmlbff, i)))
{
free(htmlbff);
printf("\nError! Memory allocation failed!");
return 0x00;
}
htmlbff = tmp;
}
q += c;
}

它因内存泄漏而崩溃....但是以下代码不会崩溃:

while((c = recv(sock, htmlbff + q, MAXDATASIZE, 0)) > 0)
{
if((i - q) < MAXDATASIZE)
{
i *= 2;
if(!(tmp = realloc(htmlbff, i)))
{
free(htmlbff);
printf("\nError! Memory allocation failed!");
return 0x00;
}
}
htmlbff = tmp;
q += c;
}

如何将 htmlbff = tmp; 移到 if 语句之外来解决这个问题?在 if 语句中似乎没有将 htmlbff 设置为 tmp ...我非常困惑。

最佳答案

/*
* I assume these exist, and more or less fit the requirements described.
* They don't have to be these specific numbers, but they do need to have
* the specified relationships in order for the code to work properly.
*/
#define MAXDATASIZE 4096 /* any number here is ok, subject to rules below */
int i = 4096; // i >= MAXDATASIZE, or the first recv can trigger UB
char *htmlbff = malloc(i); // ITYK you can't realloc memory that wasn't malloc'd
int q = 0; // q <= i-MAXDATASIZE

/* maybe other code */

while((c = recv(sock, htmlbff + q, MAXDATASIZE, 0)) > 0)
{
/*
* You've already just read up to MAXDATASIZE bytes.
* if (i-q) < MAXDATASIZE, then **your buffer is already too small**
* and that last `recv` may have overrun it.
*/
if((i - q) < MAXDATASIZE)
{
... reallocate htmlbff ...
}
/* Then you bump q...but too late. lemme explain in a sec */
q += c;
}

假设您连续两次接收到 4096 字节。发生的事情是:

  1. 第一次读取 4096 字节,从 htmlbff + 0 开始。
  2. 因为 q 仍然是 0,i - q == 4096,所以没有分配。
  3. q 增加了 4096。
  4. 第二次读取 4096 字节,从 htmlbff + 4096 开始。但是等等,因为我们上次迭代没有调整它的大小,htmlbff 只有 4096 字节大,整个读取溢出缓冲区!
  5. 如果幸运的话,溢出会导致段错误并且程序终止。如果你不是,那么 CPU 只是士兵,从这里开始的任何行为都是未定义的。此时即使诊断进一步的问题也没有什么意义,因为 $DEITY 知道代码刚刚破坏了什么。

试试这个...

while((c = recv(sock, htmlbff + q, MAXDATASIZE, 0)) > 0)
{
/* **First**, bump `q` past the stuff you just read */
q += c;

/*
* **Now** check the buffer. If i-q is too small at this point, the buffer is
* legitimately too small for the next read, and also hasn't been overrun yet.
*/
if((i - q) < MAXDATASIZE)
{
/* This temp pointer **really** should be limited in scope */
char *double_sized;

/* Note that otherwise, i'm using the "broken" resize code.
* It should work fine.
*/
i *= 2;
if(!(double_sized = realloc(htmlbff, i)))
{
free(htmlbff);
printf("\nError! Memory allocation failed!");
return 0x00;
}
htmlbff = double_sized;
}
}

关于c - 在 if 语句中无法重新分配内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12113819/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com