首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在malloc后出现“无效写入8”错误

在malloc后出现“无效写入8”错误
EN

Stack Overflow用户
提问于 2022-10-10 20:11:59
回答 2查看 83关注 0票数 0

因此,我希望解析类似shell的命令,并将其存储在char**上,以便将其作为execv系统调用上的参数传递。在下面的函数中,解析和存储工作正常。

代码语言:javascript
复制
char ** input_delimit(char *command){            // 19
    char **retval;                               // 20
    const char space[2]=" ";                     // 21
    int i=0;                                     // 22
    retval=(char**)malloc(sizeof(char*));        // 23
    retval[i]=(char*)malloc(sizeof(char));       // 24
    retval[i]=strtok(command,space);             // 25
    while(retval[i]!=NULL){                      // 26
        i++;                                     // 27
        retval[i]=(char*)malloc(sizeof(char));   // 28
        retval[i]=strtok(NULL,space);            // 29
    }                                            // 30
    return retval;                               // 31
}                                                // 32

当我运行我的代码时,我得到以下错误消息(尽管它正确地完成了我希望它做的事情)。这一切为什么要发生?

代码语言:javascript
复制
==824== Invalid write of size 8
==824==    at 0x109410: input_delimit (shell.c:28)
==824==    by 0x109493: execute_command (shell.c:35)
==824==    by 0x109600: main (shell.c:64)
==824==  Address 0x4a489d8 is 0 bytes after a block of size 8 alloc'd
==824==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==824==    by 0x1093A7: input_delimit (shell.c:23)
==824==    by 0x109493: execute_command (shell.c:35)
==824==    by 0x109600: main (shell.c:64)
==824==
==824== Invalid write of size 8
==824==    at 0x109439: input_delimit (shell.c:29)
==824==    by 0x109493: execute_command (shell.c:35)
==824==    by 0x109600: main (shell.c:64)
==824==  Address 0x4a489d8 is 0 bytes after a block of size 8 alloc'd
==824==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==824==    by 0x1093A7: input_delimit (shell.c:23)
==824==    by 0x109493: execute_command (shell.c:35)
==824==    by 0x109600: main (shell.c:64)
==824==
==824== Invalid read of size 8
==824==    at 0x109450: input_delimit (shell.c:26)
==824==    by 0x109493: execute_command (shell.c:35)
==824==    by 0x109600: main (shell.c:64)
==824==  Address 0x4a489d8 is 0 bytes after a block of size 8 alloc'd
==824==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==824==    by 0x1093A7: input_delimit (shell.c:23)
==824==    by 0x109493: execute_command (shell.c:35)
==824==    by 0x109600: main (shell.c:64)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-10 20:23:24

这..。

retval=(char\*\*)malloc(sizeof(char\*));

..。分配足够的空间来存储一个char *

这..。

retval[i]=(char\*)malloc(sizeof(char));

..。为一个char分配空间,并将指向它的指针分配给retval[i]。当您用另一个指针覆盖指针时,该空格随后会泄漏:

retval[i]=strtok(command,space);

但现在主要的问题来了。retval指向足以容纳一个char *的空间。因此,每一次迭代.

i++; retval[i]=(char\*)malloc(sizeof(char)); retval[i]=strtok(NULL,space);

..。超出分配空间的范围(更不用说分配和立即泄漏另一个块)。我希望瓦伦能注意到,并发出你所描述的那样的诊断结果。

建议:

  1. 首先为至少两个块分配空间,因为对于任何有效的命令,至少都需要这样的空间。

  1. 跳过了那些单一的char分配。它们不仅没有用处,而且实际上是有害的。--

  1. 当您在未到达命令末尾的情况下填充所分配的空间时,请使用realloc()获取更多单词的空间。这意味着您必须跟踪您已经分配了多少空间。示例:

char *temp = realloc( retval,new_capacity * sizeof(*retval));if (!temp) { //句柄分配失败. }

票数 1
EN

Stack Overflow用户

发布于 2022-10-10 20:20:21

您只为一个指针动态分配内存。

代码语言:javascript
复制
   retval=(char**)malloc(sizeof(char*));

所以这个循环

代码语言:javascript
复制
   while(retval[i]!=NULL){
           i++;
           retval[i]=(char*)malloc(sizeof(char));
           retval[i]=strtok(NULL,space);
   }

调用未定义的行为。

此外,这些陈述

代码语言:javascript
复制
retval[i]=(char*)malloc(sizeof(char));
retval[i]=strtok(command,space)

产生内存泄漏,因为内存被分配,其地址被分配给指针retval[i],在下一个语句中,指针被重新分配。因此,分配的内存的地址丢失。

您需要在while循环中对指针realloc使用retval

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74020238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档