code崩溃,除非我把printf语句在它 [英] Code crashes unless I put a printf statement in it

查看:155
本文介绍了code崩溃,除非我把printf语句在它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是code从我使用一个数组库片段。这个运行在windows很好,但是当我用gcc编译在Linux上,如果在这个函数中崩溃。试图缩小问题的时候,我加了printf语句给它,而code停止崩溃。

This is a snippet of code from an array library I'm using. This runs fine on windows, but when I compile with gcc on linux if crashes in this function. when trying to narrow down the problem, I added a printf statement to it, and the code stopped crashing.

void _arrayCreateSize( void ***array, int capacity )
{
    (*array) = malloc( (capacity * sizeof(int)) + sizeof(ArrayHeader) );
    ((ArrayHeader*)(*array))->size = 0;
    ((ArrayHeader*)(*array))->capacity = capacity;
    // printf("Test!\n");
    *(char**)array += sizeof(ArrayHeader);
}

只要是的printf取出它再次开始对我崩溃。我完全感到困惑,为什么它的发生。

As soon as that printf is taken out it starts crashing on me again. I'm completely baffled as to why it's happening.

推荐答案

在函数中的最后一行是不是做什么之意。在code是费解的不可入点。

The last line in the function is not doing what was intended. The code is obscure to the point of impenetrability.

看来,我们的目标是分配 INT 的数组,因为的sizeof(INT)中第一存储器分配。最起码,如果你是为了要分配结构数组的指针,你需要使用的sizeof(SOMETYPE *),一些指针类型的大小(的sizeof(无效*)会做)。作为写入,这将在64位的环境可怕失败。

It appears that the goal is to allocate an array of int, because of the sizeof(int) in the first memory allocation. At the very least, if you are meant to be allocating an array of structure pointers, you need to use sizeof(SomeType *), the size of some pointer type (sizeof(void *) would do). As written, this will fail horribly in a 64-bit environment.

该数组分配与随后阵列适当的结构头( ArrayHeader )。返回的值应该是数组正确的开始;该ArrayHeader将presumably由指针减法找到。这是丑陋的罪过,并且难以维护引导。它可以作出的工作,但它需要格外小心,和(布赖恩Kernighan的说):如果你当你写的code是尽可能巧妙,你是如何以往任何时候都调试它?

The array is allocated with a structure header (ArrayHeader) followed by the array proper. The returned value is supposed to the start of the array proper; the ArrayHeader will presumably be found by subtraction from the pointer. This is ugly as sin, and unmaintainable to boot. It can be made to work, but it requires extreme care, and (as Brian Kernighan said) "if you're as clever as possible when you write the code, how are you ever going to debug it?".

不幸的是,最后一行是错误的:

Unfortunately, the last line is wrong:

void _arrayCreateSize( void ***array, int capacity )
{
    (*array) = malloc( (capacity * sizeof(int)) + sizeof(ArrayHeader) );
    ((ArrayHeader*)(*array))->size = 0;
    ((ArrayHeader*)(*array))->capacity = capacity;
    // printf("Test!\n");
    *(char**)array += sizeof(ArrayHeader);
}

它增加了的sizeof而不是预期的的sizeof(ArrayHeader)* sizeof的(CHAR(ArrayHeader)* sizeof的(字符*)来的地址, )。最后一行应阅读,因此:

It adds sizeof(ArrayHeader) * sizeof(char *) to the address, instead of the intended sizeof(ArrayHeader) * sizeof(char). The last line should read, therefore:

*(char *)array += sizeof(ArrayHeader);

或者,如在评论中所指出和备选答案:

or, as noted in the comments and an alternative answer:

*(ArrayHeader *)array += 1;
*(ArrayHeader *)array++;

我顺便指出函数名不应该真正开始以下划线。开始以下划线外部名称被保留(C编译器和库)的实施。

I note in passing that the function name should not really start with an underscore. External names starting with an underscore are reserved to the implementation (of the C compiler and library).

问题问:为什么在的printf()语句'修复'的东西。答案是因为它周围移动的问题。你已经有了一个Heisenbug因为分配的内存的滥用和的presence的的printf()设法改变code的行为咯。

The question asks "why does the printf() statement 'fix' things". The answer is because it moves the problem around. You've got a Heisenbug because there is abuse of the allocated memory, and the presence of the printf() manages to alter the behaviour of the code slightly.


  1. 运行在的valgrind 程序。如果没有它,得到它。

  2. 修改了code,这样函数从检查返回值的malloc(),因此它返回一个指向一个结构分配的数组。

  3. 使用中的迈克尔·伯尔答案列出的更清晰code。

  1. Run the program under valgrind. If you don't have it, get it.
  2. Revise the code so that the function checks the return value from malloc(), and so it returns a pointer to a structure for the allocated array.
  3. Use the clearer code outlined in Michael Burr's answer.

这篇关于code崩溃,除非我把printf语句在它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆