当前位置:  开发笔记 > 程序员 > 正文

Malloc,strlen,strcat

如何解决《Malloc,strlen,strcat》经验,为你挑选了2个好方法。

以下是我正在编写的程序开头的一段代码(包含错误).

    char *name;
    char *name2;

    if (argn != 2) {
        printf("You have to enter the name of the input file");
        return 1;
    }

    name = malloc(strlen(arg[1]) + 1);      
    name2 = malloc(strlen(arg[1]) + 1);

    strcpy(name, arg[1]); 
    strcpy(name2, arg[1]);

    strcat(name2, "-results.pdb");  

这里有一个错误strcat,实际上name2没有足够的大小来执行上面的操作.然而strcat执行没有问题.但是后来在程序的一个完全不相关的部分中,在此之后初始化的另一个数组的操作strcat给出了错误.它是一个整数数组,我为其分配值,并在分配所有值之前给出错误.我假设因为上面的操作在name2中没有足够的内存,所以"某种程度上"会影响下一个初始化的数组.我想了解:

1-这里可能发生什么,以便无法写入name2的额外信息会影响稍后声明的其他数组?

2-我可能无法在更复杂的程序中轻易地回溯这个问题,因为错误发生在其他地方而不是strcat中.我怎样才能防止这种偷偷摸摸的错误,比如memory problematic影响其他地方完全不相关的数组?



1> Jens..:

然而strcat执行没有问题.

不,不.它返回,但它已经种下了定时炸弹.正如你稍后观察的那样.

会发生什么是未定义的行为.你已写入内存,你不能写.无论存储什么,现在都有垃圾,任何代码都希望找到有意义的价值,现在行为不端.特别是如果malloc内部数据被破坏,则在尝试重新分配或稍后释放内存时,观察是随机崩溃.

正确的方法是分配内存

name2 = malloc(strlen(arg[1]) + sizeof "-results.pdb");

这样可以处理终止NUL的"+1",因为它sizeof "-results.pdb"是13.

更容易使用asprintf(不是ISO C,但可以在任何当代Unix上使用),它根据需要分配内存:

asprintf(&name2, "%s-results.psb", arg[1]);

那里!没有strlen,没有strcat,没有sizeof,没有malloc.只是一个一体化的电话做正确的事TM.


@Sina虽然您可能认为您观察到的行为是一种定义,因为它是可重复的,您应该考虑如果使用不同的优化选项,编译器的下一个版本或向程序添加更多代码,行为可能会发生巨大变化.标准是否应该说出程序错误可能出现的多种方式会发生什么?不,那是不可能的.所以它未定义.

2> coredump..:

就像strcat的手册对你说的那样:

char *strcat(char *dest, const char *src);

strcat()函数将src字符串附加到dest字符串,覆盖dest末尾的终止空字节('\ 0'),然后添加一个终止空字节.字符串可能不重叠,dest字符串必须有足够的空间用于结果. 如果dest不够大,程序行为是不可预测的; 缓冲区溢出是攻击安全程序的最佳途径.

如此不可预测意味着"一切都可能发生",你的情况就是一种事物.

你应该知道,一切都是真实的,所以程序可能会在strcat调用时崩溃,甚至可能按预期工作(这一次),可能会在其他地方崩溃,因为它已经破坏了malloc内部使用的一些内存,例如,现在它不知道该取消什么.它实际上取决于您的系统以及内存所在的位置char *dest,每次运行程序时这可能会有所不同.

这就是为什么它总是更好用strncat,所以你可以指定缓冲区大小,甚至可以asprintf用于字符串连接,它会为你分配尽可能多的内存,因为它是需要的.

对于你的例子,你会写这样的东西:

char *newstr = NULL;
asprintf(&newstr, "%s%s", name2,"-results.pdb");

然后你将有一个指向新的malloced字符串的指针,在你的newstr,不要忘记在之后释放它.


该手册页应该使用技术术语**未定义的行为**而不是**不可预测的**.
推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有