相关疑难解决方法(0)

何时以及为什么操作系统会在malloc/free/new/delete上将内存初始化为0xCD,0xDD等?

我知道操作系统有时会使用某些模式(如0xCD和0xDD)初始化内存.我想知道的是何时以及为什么会发生这种情况.

什么时候

这是否特定于编译器使用?

对于这个,malloc/new和free/delete的工作方式是否相同?

它是特定于平台的吗?

它会出现在其他操作系统上,例如Linux或VxWorks吗?

为什么

我的理解是这只发生在Win32调试配置中,它用于检测内存溢出并帮助编译器捕获异常.

你能举一个关于这个初始化如何有用的实际例子吗?

我记得读过一些东西(可能在Code Complete 2中),在分配内存时将内存初始化为已知模式是好的,某些模式会触发Win32中的中断,这将导致调试器中出现异常.

这有多便携?

c c++ memory memory-management

120
推荐指数
3
解决办法
3万
查看次数

悬空指针和内存泄漏之间的区别

我不明白悬空指针和内存泄漏之间的区别.这两个术语有何关联?

c

76
推荐指数
4
解决办法
10万
查看次数

free()将内存归零吗?

直到今天,我仍然相信,调用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 free gcc memory-management clang

35
推荐指数
6
解决办法
4740
查看次数

如果main()没有返回int值会发生什么?

我知道在C编译器中,该main()函数由_start()函数调用,该函数具有如下代码:

exit(main()); // return value of main is returned
Run Code Online (Sandbox Code Playgroud)

如何_start()工作的时候main()不返回int,例如,如果它的返回类型void,float或者其他什么东西?

c c++

21
推荐指数
4
解决办法
6463
查看次数

为什么堆栈填充0xCCCCCCCC

我目前正在拆解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)

assembly disassembly

17
推荐指数
1
解决办法
2251
查看次数

用函数计算C中的数组长度

我想制作一个计算传递数组大小的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())

问候!

c arrays

11
推荐指数
2
解决办法
7万
查看次数

thread_local shared_ptr 对象在销毁时导致 sigsegv

我有一个程序,用于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 …

c++ multithreading mingw mingw-w64 c++11

11
推荐指数
1
解决办法
256
查看次数

在Win32调试版本中,什么可以导致VTable指针为0xdddddddd?

我正在调试一个缺陷,并将其缩小到对象的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).

一些说明:

  • 它是一个单线程应用程序,因此很可能不是竞争条件或互斥问题.
  • 似乎没有任何明显的问题,比如在访问对象之前将对象进一步向上删除.
  • 此问题似乎只能在Windows 2008服务器上重现,但不能在Windows 7上重现.

有关如何进一步调试的任何建议?

c++ debugging vtable

10
推荐指数
1
解决办法
1万
查看次数

"nop dword ptr [rax + rax]"x64汇编指令有什么作用?

我正在尝试理解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,但我从来没有用那种操作见过它.

有人可以解释它是做什么的吗?

assembly x86-64 cpu-architecture visual-studio nop

10
推荐指数
2
解决办法
2945
查看次数

C中的变量声明及其内存地址

我创建了一个简单的程序:

#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,p2p3有趣的是这些值有不同之处12.我想知道这背后的原因.为什么地址不同12

注意:每次执行程序时都会发生这种情况.

输出:

在此输入图像描述


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

当变量是char类型时. 在此输入图像描述


当变量是长类型时 在此输入图像描述


当我声明int数组时,每个数组的大小为1. 在此输入图像描述


当第二个声明的数组的大小为2时,它会获得额外的4字节偏移量. 在此输入图像描述

c memory pointers visual-c++

8
推荐指数
2
解决办法
2593
查看次数