Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果我在用calloc分配的内存之外设置一个值,会发生什么?_C_Valgrind_Calloc - Fatal编程技术网

如果我在用calloc分配的内存之外设置一个值,会发生什么?

如果我在用calloc分配的内存之外设置一个值,会发生什么?,c,valgrind,calloc,C,Valgrind,Calloc,考虑以下几点: int* x = calloc(3,sizeof(int)); x[3] = 100; 位于函数内部的 编译和运行程序时没有错误,但使用valgrind运行时,会得到大小为4的无效写入 我知道我正在访问一个超出我用calloc分配的内存空间,但我试图理解实际发生的事情 堆栈中的某个地址的值是否仍然为100?因为肯定有比我用calloc分配的内存更多的可用内存。valgrind错误更像是一个“嘿,你可能不是有意这么做的?”你正在为3个整数元素分配内存,但正在访问第4个元素x[3]

考虑以下几点:

int* x = calloc(3,sizeof(int));
x[3] = 100;
位于函数内部的

编译和运行程序时没有错误,但使用valgrind运行时,会得到大小为4的无效写入

我知道我正在访问一个超出我用calloc分配的内存空间,但我试图理解实际发生的事情


堆栈中的某个地址的值是否仍然为100?因为肯定有比我用calloc分配的内存更多的可用内存。valgrind错误更像是一个“嘿,你可能不是有意这么做的?”

你正在为3个整数元素分配内存,但正在访问第4个元素x[3]。因此,valgrind发出了警告消息。编译器不会对此抱怨。

您正在为3个整数元素分配内存,但正在访问第4个元素x[3]。因此,valgrind发出了警告消息。编译器不会对此抱怨。

无法保证x[3]之前的空间分配了什么,或者将来会在那里写入什么。alinsoar提到x[3]本身不会导致未定义的行为,但是您不应该尝试从那里获取或存储值。通常情况下,您可能能够毫无问题地写入和访问此内存位置,但编写依赖于到达分配阵列外部的代码会让您自己在将来很难发现错误

堆栈中的某个地址的值是否仍然为100


使用calloc或malloc时,数组的值实际上不在堆栈上。这些调用用于动态内存分配,这意味着它们被分配到称为堆的单独内存区域中。这允许您从堆栈的不同部分访问这些数组,只要您有指向它们的指针。如果数组在堆栈上,写入超过边界将有可能覆盖函数中包含的其他信息,如在最坏的情况下返回位置。

无法保证x[3]之后的空间中分配了什么或将来将写入什么。alinsoar提到x[3]本身不会导致未定义的行为,但是您不应该尝试从那里获取或存储值。通常情况下,您可能能够毫无问题地写入和访问此内存位置,但编写依赖于到达分配阵列外部的代码会让您自己在将来很难发现错误

堆栈中的某个地址的值是否仍然为100

使用calloc或malloc时,数组的值实际上不在堆栈上。这些调用用于动态内存分配,这意味着它们被分配到称为堆的单独内存区域中。这允许您从堆栈的不同部分访问这些数组,只要您有指向它们的指针。如果数组在堆栈上,写入超过边界将有可能覆盖函数中包含的其他信息,最坏的情况是返回位置

堆栈中的某个地址的值是否仍然为100

首先,calloc在堆而不是堆栈上分配内存

现在,关于这个错误

当然,在大多数情况下,程序运行时都有足够的内存可用。但是,当您为x字节分配内存时,内存管理器会查找某个大小相同的空闲内存块+如果calloc请求更大的内存来存储一些辅助信息,则可能会找到更多的内存块,但无法保证该内存块后的字节用于何处,甚至不能保证它们不是只读的,也不能被您的程序访问

所以任何事情都有可能发生。在这种情况下,如果内存就在那里等待程序使用它,则不会发生可怕的事情,但如果该内存被程序中的其他东西使用,则值将被弄乱,或者最糟糕的是,程序可能会因为访问不应该访问的东西而崩溃

因此,应认真对待valgrind误差

C语言不需要对数组访问进行边界检查,大多数C编译器也不实现它。此外,如果使用变量大小而不是常量值3,则在编译期间数组大小可能未知,并且无法检查访问是否超出范围

堆栈中的某个地址的值是否仍然为100

首先,calloc在堆而不是堆栈上分配内存

现在,关于这个错误

当然,在大多数情况下,程序运行时都有足够的内存可用。但是,当您为x字节分配内存时,内存管理器会查找某个精确大小的空闲内存块+如果calloc请求更大的内存来存储一些辅助信息,则可能会找到更多的内存块。对于该内存块之后的字节的用途,没有任何保证,甚至没有任何保证 e不是只读的,或者可以被您的程序访问

所以任何事情都有可能发生。在这种情况下,如果内存就在那里等待程序使用它,则不会发生可怕的事情,但如果该内存被程序中的其他东西使用,则值将被弄乱,或者最糟糕的是,程序可能会因为访问不应该访问的东西而崩溃

因此,应认真对待valgrind误差


C语言不需要对数组访问进行边界检查,大多数C编译器也不实现它。此外,如果使用变量大小而不是常量值3,则在编译期间数组大小可能未知,并且无法检查访问是否超出限制。

这样做的行为就是所谓的。 从字面上说,任何事情都可能发生,或者什么都不会发生

即使你很愚蠢,我也会给你额外的分数来测试Valgrind

实际上,您可能会在数组之后的内存空间中找到值100


当心。

这样做的行为就是所谓的。 从字面上说,任何事情都可能发生,或者什么都不会发生

即使你很愚蠢,我也会给你额外的分数来测试Valgrind

实际上,您可能会在数组之后的内存空间中找到值100

小心

我知道我正在访问一个超出我用calloc分配的内存空间,但我试图理解实际发生的事情

实际发生的事情并不明确;这完全取决于被覆盖的内容。只要不覆盖任何重要内容,代码就会按预期运行

您可能会破坏动态分配的其他数据。你可能会破坏一些堆簿记

该语言不对数组访问强制执行任何类型的边界检查,因此,如果读取或写入超过数组末尾,则无法保证会发生什么

我知道我正在访问一个超出我用calloc分配的内存空间,但我试图理解实际发生的事情

实际发生的事情并不明确;这完全取决于被覆盖的内容。只要不覆盖任何重要内容,代码就会按预期运行

您可能会破坏动态分配的其他数据。你可能会破坏一些堆簿记


该语言不对数组访问强制执行任何类型的边界检查,因此,如果读取或写入超过数组末尾,则无法保证会发生什么

这不回答问题这不回答问题calloc分配的内存不在堆栈上,而是在堆中。您正在设置超过分配大小的前4个字节。这些字节可以包含以下内容:程序分配的下一个对象的前4个字节;调试堆管理器专门为捕获此类错误而分配的未使用空间;堆管理器的内部数据结构告诉它分配了什么、什么是空闲的以及下一个空闲块在哪里。根据您所采取的措施,结果可能从某个不可预测的点的崩溃,到数据损坏,甚至什么都没有。calloc分配的内存不在堆栈上,而是在堆中。您正在设置超过分配大小的前4个字节。这些字节可以包含以下内容:程序分配的下一个对象的前4个字节;调试堆管理器专门为捕获此类错误而分配的未使用空间;堆管理器的内部数据结构告诉它分配了什么、什么是空闲的以及下一个空闲块在哪里。根据您所采取的措施,结果可能会从某个不可预测的点的崩溃,到数据损坏,甚至什么都没有。