首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Malloc()的奇怪副作用

Malloc()的奇怪副作用
EN

Stack Overflow用户
提问于 2010-12-13 09:30:21
回答 4查看 602关注 0票数 1

因此,我正在为一个简单的shell编写一个C程序。不是很难,但我遇到了一个很奇怪的问题,我无法解释。我试图在一个结构中创建一个二维数组来表示一个命令及其参数。例如,对于命令"ls -l“,我希望第一个元素是"ls”,第二个元素是"-l“。似乎工作得很好,除了malloc将"ls“改为"ms”。对于其他命令也是如此,第一个字符是递增的;不是在malloc之前,而是紧跟在malloc之后。

这就是有问题的代码块……

代码语言:javascript
运行
复制
    printf ("PRE MALLOC: %c\n", ret_val->args[0][0]);
    printf ("[0] %p\n", ret_val->args[0]);
    ret_val->args[1] = (char*) malloc ((3) * sizeof (char));
    printf ("[0] %p\n", ret_val->args[0]);
    printf ("[1] %p\n", ret_val->args[1]);
    printf ("POST MALLOC: %c\n", ret_val->args[0][0]);

我要做的就是分配一个3( -l + null )字符数组来保存args1中的"-l“。这些都不是真正的硬编码,但我认为这更好地说明了这一点。

输出结果是这样的。

PRE MALLOC: L

80613b0

80613b0

1 80613b8

MALLOC后:M

那么这两个地址没有重叠,或者有什么奇怪的事情,但是第一个数组的第一个字符是递增的?如果我忽略了一些愚蠢的事情,我很抱歉。但我想不出任何原因为什么会发生这种情况。

有什么想法吗?

谢谢,

对于某些上下文,这里有更多的代码。

代码语言:javascript
运行
复制
int lcv;
int numargs;
int numchars;
int offset;
int bool;

TCommand* ret_val;
char** tmp;

ret_val = (TCommand*) malloc ( sizeof (TCommand) );
ret_val->cmd = NULL;
ret_val->args = NULL;

/* CMD */
lcv = 0;
numargs = 0;
numchars = 0;
offset = 0;

/* Remove initial whitespace */
while (input[offset] == ' ')
{
    ++offset;
}

lcv = offset;

/* Loop through command string */
while ( input[lcv] != ' ' && input[lcv] != 0 && input[lcv] != '&')
{
    ++numchars;
    ++lcv;
}

ret_val->cmd = (char*) malloc ( (numchars+1) * sizeof(char));

/* Copy to command string */
memcpy (ret_val->cmd, &(input[offset]), (numchars * sizeof (char)));
ret_val->cmd[numchars] = 0;
offset += numchars;

/* Copy command string into first argument */
ret_val->args = (char**) malloc ( sizeof (char*));
memcpy (ret_val->args[numargs++],ret_val->cmd, (numchars+1) * sizeof(char));

bool = 1;
while ( bool )
{

    /* Remove initial whitespace */
    while (input[offset] == ' ')
    {
        ++offset;
    }

    lcv = offset;

    if ( input[lcv] == 0 )
    {
        bool = 0;
    }
    else
    {
        ++numargs;
        tmp = (char**) realloc (ret_val->args, numargs * sizeof (char*));
        ret_val->args = tmp;
        numchars = 0;

        while ( input[lcv] != ' ' && input[lcv] != 0 &&
            input[lcv] != '&')
        {
            ++numchars;
            ++lcv;
        }

                printf ("PRE MALLOC: %c\n", ret_val->args[0][0]);
                printf ("[0] %p\n", ret_val->args[0]);
                    ret_val->args[1] = (char*) malloc ((2) * sizeof (char));
                printf ("[0] %p\n", ret_val->args[0]);
                printf ("[1] %p\n", ret_val->args[1]);
                printf ("POST MALLOC: %c\n", ret_val->args[0][0]);
                fflush(stdout);
        memcpy (ret_val->args[numargs-1],&(input[offset]),numchars * sizeof (char));
        ret_val->args[numargs-1][numchars] = 0;
        offset += numchars;
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-13 10:25:58

这段代码:

代码语言:javascript
运行
复制
/* Copy command string into first argument */
ret_val->args = (char**) malloc ( 2 * sizeof (char*));
memcpy (ret_val->args[numargs++],ret_val->cmd, (numchars+1) * sizeof(char));

通过未初始化的指针ret_val->args[0]进行复制。尝试:

代码语言:javascript
运行
复制
/* Copy command string into first argument */
ret_val->args = malloc(2 * sizeof ret_val->args[0]);
ret_val->args[numargs] = malloc(numchars + 1);
memcpy(ret_val->args[numargs++], ret_val->cmd, numchars + 1);

(请注意,语言将sizeof(char)定义为1)。

票数 4
EN

Stack Overflow用户

发布于 2010-12-13 10:08:01

问题不在于您显示的片段,而在于您没有显示的代码中的某个地方。

因此,您需要从头开始构建示例-显示结构声明、内存管理和对结构所做的复制。

票数 0
EN

Stack Overflow用户

发布于 2010-12-13 10:18:13

这听起来像是堆损坏的典型例子。

您所看到的很可能是malloc()调用用返回值覆盖了args[0]所指向的字符串的结果。如果args数组实际上没有足够的空间容纳第二个参数,就会发生这种情况。通过写入args[1],您将覆盖argv[0]所指向的字符串的内容,我怀疑您在分配args数组后立即使用strdup()调用或类似方法分配了该字符串的内容。

由于堆向上增长,并且假设没有介入的free()调用,通过超越动态分配的数组的界限,增加了扰乱随后立即分配的区域的机会。

我将大胆猜测,并建议您通过打印args调用的参数并检查其返回值来检查为realloc()数组分配的大小。

编辑:

显然不是在这种情况下。似乎argv[0]指针实际上可能是未初始化的,而不会导致分段错误。有趣的是。

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

https://stackoverflow.com/questions/4425191

复制
相关文章

相似问题

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