C++ 为什么免费在这里崩溃?

C++ 为什么免费在这里崩溃?,c++,C++,当它释放时,以下崩溃:有理由使用void* bool s = true; void* arg = &s; argument = malloc(sizeof(arg)); memcpy(argument,arg,sizeof(arg)); free(argument); 这里的论点是无效的* 为什么免费软件会使应用程序崩溃 谢谢你确定崩溃的是免费的吗?看起来更可能是memcpy调用。您正在盲目地将X字节从arg复制到参数,其中X是指针的大小。但是您不知道arg指向的数据的大小。arg指

当它释放时,以下崩溃:有理由使用void*

bool s = true;

void* arg = &s;
argument = malloc(sizeof(arg));
memcpy(argument,arg,sizeof(arg));
free(argument);
这里的论点是无效的*

为什么免费软件会使应用程序崩溃


谢谢

你确定崩溃的是免费的吗?看起来更可能是memcpy调用。您正在盲目地将X字节从arg复制到参数,其中X是指针的大小。但是您不知道arg指向的数据的大小。

arg指向bool,您正在从中复制4个字节!这就是它崩溃的原因。bool只有一个字节。

您的问题很可能在其他地方

由于您对指针的大小有一些误解,我怀疑您的程序中的其他地方存在缓冲区溢出/下溢,这会导致堆头损坏,然后在尝试遍历损坏的堆时释放崩溃

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

memcpy可以很好地读取未对齐的数据,因此即使您所在的体系结构在未对齐的访问中崩溃,这也不是问题所在

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

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

我需要得到分配的对象,它可以是任何类型的–Milo

C++不是那样工作的。malloc只能为POD类型分配内存,这些类型必须满足一些非常严格的限制。根本没有符合标准的方法来克隆完全任意类型的实例

在某些类型上可靠工作的一些方法有:

如果该类型具有具有虚拟克隆函数的基类型,则以多态方式调用克隆 如果类型为POD并且您知道大小,请使用new char[]和memcpy 此代码在VS 2010中不会崩溃。事实上,就内存管理而言,这段代码并不违法。但是是的,它并没有按预期的那样工作,因为它复制了垃圾。假设是32位环境,则分配4个字节,并将参数设置为指向这4个字节。然后将arg指向的内存中的4个字节复制到参数指向的4个字节中。是的,arg指向的4个字节中有3个是垃圾,但它们在那里。编译器将在堆栈上为bool s分配4个字节,而不是1个字节。堆栈需要以4字节的块分配。所以内存在那里,尽管有3个字节中有垃圾


我怀疑您有一个来自其他地方的损坏堆,因此对free的调用恰好在此崩溃。

根据您的评论判断,您认为sizeofarg正在返回arg指向的任何对象的实际大小。这是错误的。它返回一个void*指针的大小

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


如果free在您给它一个有效指针时崩溃,则表示堆被破坏。由于在您展示的示例中没有任何代码会使指针无效或垃圾堆,因此在您开始编写此代码之前,我必须断定问题出在其他地方。

您确定要使用sizeofarg吗?这将给出一个空*的大小,而不是arg指向的任何对象的大小。@Milo:如果我不知道对象的大小怎么办?-如果是这样的话,你怎么能指望复制它呢?@Milo:如果你仍然认为它在免费时崩溃了,那么就把免费的删除,看看它是否崩溃!如果它仍然崩溃,请参阅我的答案和其他关于memcpy问题的答案。-1因为没有显示参数声明。@Andrey和@Michael:代码可能实际上是免费崩溃的,尽管这不是坏代码。稍后崩溃是缓冲区溢出的一种可能行为,即使它是读取而不是写入。有没有办法在不知道对象是什么的情况下知道它的大小?@Milo:no.cruft满足最小注释长度no。你需要知道这个物体是什么。如果它是一个结构,那么sizeofstruct x将起作用。如果它是一个字符串,请使用strlenag。为什么我说对了一半,free本身没有问题。bool[可能]只有一个字节[在您的平台上]。而读取变量之外的额外字节是不好的,这本身不太可能导致崩溃,除非变量恰好位于不太可能的内存不可读区域附近。@TheUndeadFish:+1,尤其是对于堆栈上向下增长的局部变量。尽管您正确地认为memcpy复制的字节太多,那不太可能是坠机的原因。我同意。如果程序已经写过了其他堆分配数组/缓冲区/对象/任何东西的末尾,那么它很可能已经以某种方式损坏了堆,直到稍后的调用才显示出来
免费。欢迎来到马里奥。同意崩溃的原因,+1超出了我的答案并实际运行了代码片段。因为我想要更多像你这样懂指针的人。哇,这是你对这个问题的第三次回答。第三次是魅力?我认为这一次是正确的,尽管其他人已经提出了同样的观点。
#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;
}