【问题标题】:C buffer overflowC 缓冲区溢出
【发布时间】:2012-08-20 22:24:52
【问题描述】:

我尝试创建一个函数,用str2 替换文本t 中所有出现的str1,但我不断收到“缓冲区溢出” 错误消息。你能告诉我我的功能有什么问题吗?

#include <stdio.h>
#include <string.h>
#include <assert.h>

//replace all *str1 in *t with *str2, put the result in *x, return *x
char * result(char *str1,char *str2,char *t)
{
    char *x=NULL,*p=t,*r=t;
    x=malloc(400*sizeof(char));
    assert(x!=NULL);
    x[0]='\0';
    r=strstr(t,str1); //r is at the first occurrence of str1 in t, p is at the beginning of t
    while(r!=NULL)
    {
        strncat(x,p,r-p); //copy r-p chars from p to x
        strcat(x,str2); //copy str2 to x
        p=r+strlen(str1); //p will be at the first char after the last occurrence of str1 in t
        r=strstr(r+strlen(str1),str1); //r goes to the next occurrence of str1 in t
    }
    strcat(x,p);
    return x;
}

我没有使用gets() 函数读取任何char 数组。

我的编译器是 gcc 版本 4.6.3


我更新了代码,它可以工作,但结果不是预期的。

main()函数:

int main(void)
{
    char *sir="ab",*sir2="xyz",*text="cabwnab4jkab",*final;
    final=result(sir,sir2,text);
    puts(final);
    free(final);
    return 0;
}

打印字符串:

b

我期待cxyzwnxyz4jkxyz

【问题讨论】:

  • 你不能返回x,它是函数本地的。
  • 查看编辑:你的结果和strcat vs. strcpy
  • 在调试器中单步执行此代码或每次通过循环打印出变量的值应该可以相当清楚问题出在哪里。
  • sizeof(char) 是 C 中的定义 1。虽然它是一种次要的风格,但它表明你对语言的理解存在更深层次的问题。

标签: c string char buffer-overflow


【解决方案1】:

看起来你的strncpy 参数混淆了:第二个参数是 source 字符串,而不是要复制的字符数的限制,应该是第三个参数:

 strncpy(x, p, r - p); // copy r - p chars from p to x

此外,您想使用strcat 而不是strcpy。使用strcpy,您只需每次都用替换字符串覆盖结果的内容。使用strcat,请务必在开始前使用\0 初始化结果。

最后,您要从函数返回对局部变量 x 的引用:您不能这样做,因为函数返回后内存不可用。

【讨论】:

  • 谢谢!我会尝试动态分配
【解决方案2】:

您的代码包含很多奇怪的错误。

首先,x 是指向目标缓冲区的指针。出于某种原因,您将所有复制都直接复制到x,即所有内容都复制到缓冲区的最开始,覆盖以前复制的数据。这根本没有任何意义。你为什么这样做?您需要创建一个专用指针,以将当前目标位置保持在 x 并将数据写入该位置(而不是将其写入 x)。

我看到您编辑了代码并将复制替换为串联。嗯......即使它可能会解决问题,这仍然是糟糕的设计。 strcat/strncat 函数在好的 C 代码中没有位置。无论如何,您的代码仍然被破坏,因为您试图在未初始化的缓冲区x 上使用strcat 函数。您需要先将x 初始化为空字符串。

其次,搜索替换字符串存在一个更微妙的问题。在循环结束时,您从下一个符号 r=strstr(r+1,str1) 继续搜索,即您将搜索位置仅增加 1。我不确定这是否是您想要的。

aaaa 视为输入文本,并将aa 替换为bc 的请求。在这种情况下,您要进行多少次替换? aaaaaa 中有多少次出现? 2个还是3个?如果你想得到bcbc作为结果(2个替换),你必须将r增加strlen(str1),而不是增加1。

实际上,在当前实现中,您设置了p=r+strlen(str1),但从r+1 位置继续搜索。这将导致搜索字符串重叠出现的完全无意义的结果,如我的示例所示。试试这个

char *str1="aa",*str2="xyz",*text="aaaa",*final;
final=result(str1,str2,text);

看看会发生什么。

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 2011-09-07
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 2020-10-02
    • 2017-06-26
    相关资源
    最近更新 更多