简体   繁体   English

malloc上的分段错误

[英]Segmentation fault on malloc

After running this function many (not sure exactly how many) times, it seg faults on a simple memory allocation. 在多次(不确定确切次数)运行此功能后,它会在简单的内存分配上分段故障。 Why would this suddenly happen? 为什么会突然发生这种情况? I did notice something strange in GDB. 我确实注意到GDB中有些奇怪的地方。 In the function that calls it, normally there's 6-digit long hex value for wrd (wrd = 0x605140 for example), however on the call where it crashes, the hex value is only two digits long. 在调用它的函数中,wrd通常有6位长的十六进制值(例如,wrd = 0x605140),但是在崩溃的调用中,十六进制值只有两位数。 (wrd=0x21). (wrd = 0x21)。 I also checked the wrd->length, and it's 3. 我还检查了wrd-> length,它是3。

The line that it crashes on is... 它崩溃的那条线是...

char *word_temp = malloc(wrd->length * sizeof(char));

EDIT: 编辑:

Here's the code that creates the wrd... 这是创建wrd的代码...

while(fgets(input, 100, src) != 0)
{
    int i = 0;
    while(input[i] != '\0')
    {
        i++;
    }

    struct word *wrd = malloc(sizeof(struct word));
    wrd->letters = input;
    wrd->length = i;

If I'm getting an overflow, how do I fix that? 如果出现溢出,该如何解决?

Looks like wrd->length does not include the terminating '\\0' . 看起来wrd->length不包含终止符'\\0'

Fix 1, allocate word_temp like this: 修复1,像这样分配word_temp

char *word_temp = malloc( wrd->length + 1 );

Fix 2, include the '\\0' by modifying you length count loop: 修订2,通过修改长度计数循环来包含'\\ 0':

int i = 0;
while(input[i++] != '\0') {}

This will increase i one more time than code in the question, which is easy to see if you consider case of input being empty. 这将增加i不是代码的一个更多的时间的问题,这是很容易看到,如果你考虑的情况下, input是空的。

Note that you need to do either fix 1 or fix 2, not both. 请注意,您需要执行修复1或修复2,而不是两者。 Choose which ever works with rest of your code. 选择与其余代码一起使用的代码。


You probably have a second issue with this line: 您可能对此行有第二个问题:

wrd->letters = input;

It does not copy input, it copies the pointer. 它不复制输入,而是复制指针。 If you change contents of input , contents of wrd->letters changes too, because they point to same memory location. 如果更改input内容,则wrd->letters内容wrd->letters更改,因为它们指向相同的存储位置。 Also if input is a local char array, then once it goes out of scope, wrd->letters becomes a dangling pointer, which will be overwritten by other data, and modifying it after that will result in memory corruption. 同样,如果input是本地char数组,则一旦超出范围, wrd->letters就会变成一个悬空的指针,该指针将被其他数据覆盖,然后对其进行修改将导致内存损坏。

Possible fix (depending on rest of your code) is to use strdup : 可能的解决方法(取决于代码的其余部分)是使用strdup

wrd->letters = strdup(input);

Remember that it is now allocated from heap, so when done, you must remember to do 请记住,它现在是从堆中分配的,因此完成后,您必须记住

free(wrd->letters);

About wrd being 0x21, that indicates either memory corruption, or that you actually have two separate wrd variables, and one one is left uninitialized. 关于wrd为0x21,表示内存损坏,或者您实际上有两个单独的wrd变量,其中一个未初始化。

For example, maybe wrd is a function parameter struct word *wrd , in which case you only modify the local value in function, it does not get passed back to the caller. 例如,也许wrd是一个函数参数struct word *wrd ,在这种情况下,您仅修改函数中的本地值,不会将其传递回调用方。 To modify the pointer of caller, you need to have pointer to pointer: struct word **wrd and then do (*wrd) = malloc... and (*wrd)->letters... etc. 要修改调用者的指针,您需要有一个指向指针的指针: struct word **wrd ,然后执行(*wrd) = malloc...(*wrd)->letters...等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM