我知道操作系统有时会使用某些模式(如0xCD和0xDD)初始化内存.我想知道的是何时以及为什么会发生这种情况.
这是否特定于编译器使用?
对于这个,malloc/new和free/delete的工作方式是否相同?
它是特定于平台的吗?
它会出现在其他操作系统上,例如Linux或VxWorks吗?
我的理解是这只发生在Win32调试配置中,它用于检测内存溢出并帮助编译器捕获异常.
你能举一个关于这个初始化如何有用的实际例子吗?
我记得读过一些东西(可能在Code Complete 2中),在分配内存时将内存初始化为已知模式是好的,某些模式会触发Win32中的中断,这将导致调试器中出现异常.
这有多便携?
直到今天,我仍然相信,调用free()内存空间会释放它以供进一步分配而无需任何其他修改.特别是,考虑到这个SO问题清楚地表明free()不会将内存归零.
但是,让我们考虑这段代码(test.c):
#include<stdlib.h>
#include<stdio.h>
int main()
{
int* pointer;
if (NULL == (pointer = malloc(sizeof(*pointer))))
return EXIT_FAILURE;
*pointer = 1337;
printf("Before free(): %p, %d\n", pointer, *pointer);
free(pointer);
printf("After free(): %p, %d\n", pointer, *pointer);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
编译(GCC和Clang):
gcc test.c -o test_gcc
clang test.c -o test_clang
Run Code Online (Sandbox Code Playgroud)
结果:
$ ./test_gcc
Before free(): 0x719010, 1337
After free(): 0x719010, 0
$ ./test_clang
Before free: 0x19d2010, 1337
After free: 0x19d2010, 0
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我一直生活在谎言中还是我误解了一些基本概念?还是有更好的解释?
一些技术信息:
Linux 4.0.1-1-ARCH x86_64
gcc version 4.9.2 …Run Code Online (Sandbox Code Playgroud) 我知道在C编译器中,该main()函数由_start()函数调用,该函数具有如下代码:
exit(main()); // return value of main is returned
Run Code Online (Sandbox Code Playgroud)
如何_start()工作的时候main()不返回int,例如,如果它的返回类型void,float或者其他什么东西?
我目前正在拆解Visual Studio 2012 Express中的一些小型C程序,我注意到了二进制文件中的一种趋势.
在main函数中执行的第一组指令总是:
SUB ESP,154 ; Doesn't have to be 0x154.
.....
.....
.....
LEA EDI,DWORD PTR SS:[EBP-154]
MOV ECX,55 ; Also doesn't have to be 0x55.
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]
Run Code Online (Sandbox Code Playgroud)
那么,为什么机器用这个0xCCCCCCCC填充堆栈?我已经读过它被VC++或其他东西用作未初始化空间的标记?
然后让我说我要把一些东西放进我的缓冲区......编译器或处理器决定将它放在这个空间内的某个随机点,但是我不明白为什么它会把它放在那里......
EBP-90 > CCCCCCCC ÌÌÌÌ
EBP-8C > CCCCCCCC ÌÌÌÌ
EBP-88 > CCCCCCCC ÌÌÌÌ
EBP-84 > 00000001 ... ; Why this place?
EBP-80 > CCCCCCCC ÌÌÌÌ
EBP-7C > CCCCCCCC ÌÌÌÌ
EBP-78 > 41414141 AAAA ; Why this far from both the top …Run Code Online (Sandbox Code Playgroud) 我想制作一个计算传递数组大小的FUNCTION.
我将传递一个数组作为输入,它应该返回它的长度.我想要一个功能
int ArraySize(int * Array /* Or int Array[] */)
{
/* Calculate Length of Array and Return it */
}
void main()
{
int MyArray[8]={1,2,3,0,5};
int length;
length=ArraySize(MyArray);
printf("Size of Array: %d",length);
}
Run Code Online (Sandbox Code Playgroud)
长度应该是5,因为它包含5个元素,虽然它的大小是8(即使8会做,但5会很好)
我试过这个:
int ArraySize(int * Array)
{
return (sizeof(Array)/sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)
这将无效,因为" sizeof(Array)"将重新调整Int指针的大小.这个" sizeof"只有你在同一个功能时才有效.
实际上我从C#开始很多天回到C所以我不记得了(和失踪Array.Length())
问候!
我有一个程序,用于thread_local std::shared_ptr管理一些主要在本地线程访问的对象。但是,当线程加入并且线程局部shared_ptr正在析构时,如果程序是由MinGW(Windows 10)编译的,那么在调试时总是会出现SIGSEGV。以下是重现该错误的最少代码:
// main.cpp
#include <memory>
#include <thread>
void f() {
thread_local std::shared_ptr<int> ptr = std::make_shared<int>(0);
}
int main() {
std::thread th(f);
th.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如何编译:
g++ main.cpp -o build\main.exe -std=c++17
Run Code Online (Sandbox Code Playgroud)
编译器版本:
>g++ --version
g++ (x86_64-posix-seh-rev2, Built by MinGW-W64 project) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)
使用 gdb …
我正在调试一个缺陷,并将其缩小到对象的vtable指针0xdddddddd. 这个答案表明Win32调试版本通常会将死记忆或已删除的内存设置为此特殊值.
需要注意的是指针本身看起来有效,它只是虚函数表指针是0xdddddddd.
这是一段代码:
std::list<IMyObject*>::const_iterator it;
for (it = myObjects.begin(); it != myObjects.end(); ++it)
{
IMyObject* pMyObject = *it;
if (pMyObject == 0)
continue;
pMyObject->someMethod(); // Access violation
}
Run Code Online (Sandbox Code Playgroud)
如果我在访问冲突的行中断并观察pMyObject,我可以看到它pMyObject本身有一个有效的地址(0x08ede388)但该__vfptr成员是无效的(0xdddddddd).
一些说明:
有关如何进一步调试的任何建议?
我正在尝试理解x64编译器完成的程序集优化.
我在Windows 8.1上Release使用Visual Studio 2008 SP1IDE 编译了一个小型C++项目.
其中一行包含以下汇编代码:
B8 31 00 00 00 mov eax,31h
0F 1F 44 00 00 nop dword ptr [rax+rax]
Run Code Online (Sandbox Code Playgroud)
这是一个截图:
据我所知nop本身是do nothing,但我从来没有用那种操作见过它.
有人可以解释它是做什么的吗?
我创建了一个简单的程序:
#include <stdio.h>
int main()
{
int s1;
int s2;
int s3;
int *p1, *p2, *p3;
p1 = &s1;
p2 = &s2;
p3 = &s3;
printf("%d\n%d\n%d", p1, p2, p3);
}
Run Code Online (Sandbox Code Playgroud)
每当我运行这个程序时,它会打印指针的内存地址p1,p2而p3有趣的是这些值有不同之处12.我想知道这背后的原因.为什么地址不同12?
注意:每次执行程序时都会发生这种情况.
输出:

我在许多类型的变量中测试了相同的程序,我得到的结果是......
当变量是char类型时.

当变量是长类型时

当我声明int数组时,每个数组的大小为1.

当第二个声明的数组的大小为2时,它会获得额外的4字节偏移量.
