为什么免费崩溃?

时间:2010-10-15 18:49:09

标签: c++

下面的内容在崩溃时崩溃:(有使用void *的理由)。

bool s = true;

void* arg = &s;
argument = malloc(sizeof(arg));
memcpy(argument,arg,sizeof(arg));
free(argument);
这里的

参数是一个空白*

为什么免费崩溃应用程序?

由于

5 个答案:

答案 0 :(得分:8)

你的问题最有可能发生在其他地方。

由于您对sizeof (pointer)有一些误解我怀疑您的程序中的其他位置存在缓冲区溢出/下溢导致堆头损坏,然后free在尝试迭代时崩溃腐败的堆。

当其他人指出你从一个只有sizeof (void*)的变量中读取sizeof (bool)时,其他人都是正确的,但由于它在堆栈上,因此s以外的内存几乎可以肯定有效(它可能包含其他局部变量,函数参数或返回地址,如果无意中读取它们,则不会导致程序崩溃)。

memcpy可以很好地读取未对齐的数据,因此即使您在未对齐访问时崩溃的架构上,这也不是问题。

检查其他动态分配的缓冲区是否溢出。

编辑:我也想回应米洛对一个现已删除的问题的评论:

  

我需要获得可以分配的任何类型的对象 - Milo

C ++无法正常工作。 malloc只能为POD类型分配内存,这些内存必须满足一些非常强大的限制。完全没有符合标准的方法来克隆完全任意类型的实例。

在某些类型上可靠运行的一些方法是:

  • 如果类型的基本类型具有虚拟Clone功能,请多态调用Clone
  • 如果类型为POD且您知道尺寸,请使用new char[]memcpy

答案 1 :(得分:2)

arg指向一个bool,你要记住它的4个字节!这就是崩溃的原因。布尔只有一个字节。

答案 2 :(得分:2)

#include <string>

int main(void)
{
    void* argument;

    bool s = true;

    void* arg = &s;
    argument = malloc(sizeof(arg));
    memcpy(argument,arg,sizeof(arg));
    free(argument);

    return 0;
}

此代码在VS 2010中不会崩溃。事实上,就内存管理而言,此代码没有任何违法行为。但是,它没有按预期运行,因为它复制了垃圾。假设有32位环境,则分配4个字节并将“argument”设置为指向这4个字节。然后,您将从“arg”指向的内存中复制4个字节到“参数”指向的4个字节。是的,arg指向的4个字节中有3个是垃圾,但它们就在那里。编译器将在堆栈上为bool s分配4个字节,而不是1.堆栈需要以4个字节的块分配。所以内存就在那里,虽然有3个字节里面有垃圾。

我怀疑你的其他地方有一个损坏的堆,并且由于这个原因,对free的调用恰好在这里崩溃。

答案 3 :(得分:0)

您确定free()崩溃了吗?看起来更有可能是memcpy()电话。你是盲目地复制X字节,其中X是指针的大小,从argargument。但是你不知道arg指向的数据大小是什么。

答案 4 :(得分:0)

根据您的评论判断,您认为sizeof(arg)正在返回arg指向的实际大小。这是错的。它返回void*指针的大小。

您的memcpy正在从源的有效端之外复制数据,但这极不可能导致崩溃。

如果free在为其指定有效指针时崩溃,则表示已删除堆。由于示例中没有代码表明会使指针无效或者使堆丢弃,因此在得到此代码之前,我必须在其他地方得出结论。