calloc 创建的数组未按预期运行
Posted
技术标签:
【中文标题】calloc 创建的数组未按预期运行【英文标题】:calloc created array is not acting as expected 【发布时间】:2015-05-29 01:40:18 【问题描述】:我很无聊,想做一个程序来让我的电脑崩溃:P。我会让它无用且冗余地分配内存,直到崩溃。到目前为止我创建的代码在这里:
#include <cstdlib>
#include <cstdio>
int main(int argc, const char *argv)
int n = 0;
while (1)
n++;
int* buffer = (int*)malloc(n ^ n);
int* buffer_buffer = (int*)calloc(n, sizeof(buffer));
for (int i = 0; i < n; i++)
printf("%p", &buffer);
printf("\n");
buffer_buffer[i] = (int)buffer;
代码工作(它使计算机崩溃),但没有按预期工作。我想更深入地了解它的工作原理以及它到底在做什么,所以我设置了一些断点并决定一步通过这。我希望看到buffer_buffer
一次又一次地重新分配,其中包含n
数字buffer
,但事实并非如此。相反,我的调试器显示buffer_buffer
包含一个有时会更改的值,并且每次循环都会记录一个值(至少我希望buffer
的整数转换)。我期待 buffer_buffer
每次 for 循环出现时都会随着 n
的元素数量增长,但它只有一个元素。为了可视化这一点,这里是调试器的屏幕截图:
我又有点累了,这可能是我的循环逻辑的问题。有谁知道为什么我的程序会遇到这种意外行为?我正在使用 Microsoft Visual Studio 调试器
【问题讨论】:
旁注:^
是按位异或,所以malloc(n ^ n)
将分配零字节的内存。
@sth 从技术上讲,它将请求零字节;该实现可能会返回一个空指针,或者一个不允许您取消引用的非空指针。无论如何,某些实现可能会分配内存。
还不清楚您期望内部循环的主体做什么。 buffer
在此循环期间永远不会被修改,因此 &buffer
和 (int)buffer
每次检查时都是相同的。
【参考方案1】:
可能您的调试器不知道buffer_buffer
有多大,因为该变量被简单地声明为指向int
的指针。 (输入不正确;buffer_buffer
用于保存buffer
的值,这是一个int*
,因此buffer_buffer
必须是int*
的数组,这意味着您应该将其声明为int**
,即指向int*
序列的指针。)调试C程序的一个小挑战是数组的长度根本不存储在任何地方。你必须自己跟踪它。所以调试器也不知道。
另外,n^n
为 0,因为 ^
是 XOR 运算符。我不知道这是否是你想要的。
(实际上,分配大小没有存储在任何地方并不完全正确。它可能是,或者可能是某种近似值。但它存储在内存分配库的内部,没有办法开始吧。无论如何,它可能不正确,因为库有时分配的比你要求的多,它只记住它分配的内容,而不是你要求的。)
【讨论】:
哎呀,我曾经看过一些关于int**
的东西,但不知道那是什么。至于^
,我一定是搞混了。我的意思是使用幂运算。
另外,使用较低级别的调试器(在 asm 或二进制级别)是否有助于解决调试器问题?
@James_Parsons 如果您正在使用 MSVC,您可以在监视窗口中键入 buffer_buffer,n
以查看完整内容(从您的屏幕截图中看起来它就像是 MSVC,无法确定)。其他调试器也可能接受这种格式。
@James_Parsons:不。真的没有办法弄清楚分配的时间。你的程序应该知道。 (确实如此——数组有n
元素。)顺便说一下,你知道你每次通过那个循环都分配一个新的更大的buffer_buffer
,但永远不会释放旧的,然后只设置一个元素在新的?也许您的意思是realloc
,而不是calloc
?
@James_Parsons:此外,C 没有指数运算符。您可以使用 pow
数学库函数,但由于该函数使用浮点并且不能保证完美的准确性,因此将其截断回整数可能会导致值比您预期的少一。以上是关于calloc 创建的数组未按预期运行的主要内容,如果未能解决你的问题,请参考以下文章