不使用字符串函数连接字符串:替换字符串结尾(空字符)会产生seg错误

时间:2018-02-04 00:30:12

标签: c string segmentation-fault concatenation string-concatenation

不使用string.h函数(只想使用std libs),我想通过将作为参数提供的字符串连接到程序来创建一个新字符串。为此,我决定将参数复制到一个更大的新char数组,然后用我想要追加的字符替换字符串的结尾。

unsigned int argsize=sizeof(argv[1]);
unsigned char *newstr=calloc(argsize+5,1);
newstr=argv[1];    //copied arg string to new string of larger size
newstr[argsize+4]=oname[ns];    //copied the end-of-string null character
newstr[argsize]='.';    //this line gives seg fault
newstr[argsize+1]='X';    //this executes without any error

我相信必须有另一种更安全的方法来连接字符串而不使用字符串函数,或者通过复制char并将char附加到新的char数组中。我真的想知道这样的方法。另外,我很想知道这个段错的原因是什么。 在这里阅读:https://stackoverflow.com/a/164258/1176315我想,编译器正在使我的空字符内存块只读,但这只是猜测。我想知道这背后的真正原因。 我将非常感谢您为回答这个问题所做的一切努力。谢谢。 编辑:通过仅使用std libs,我的意思是说我不想使用strcpy(),strlen(),strcat()等函数。

2 个答案:

答案 0 :(得分:3)

  

不使用string.h函数(只想使用std库)

string.h是标准库的一部分。

unsigned int argsize=sizeof(argv[1]);

这是错误的。 sizeof没有告诉你C字符串的长度,它只是告诉你它的参数类型有多大。 argv[1]是一个指针,sizeof只会告诉你指针在你的平台上有多大(通常是4或8),无论字符串的实际内容如何。

如果你想知道一个C字符串有多长,你必须检查它的字符和计数,直到你找到一个0字符(这恰好是strlen所做的)。

newstr=argv[1];    //copied arg string to new string of larger size

不。您刚刚将argv[1]中存储的指针复制到变量newstr,偶然丢失了calloc之前返回给您的指针,因此您还有内存泄漏

要将字符串从缓冲区复制到另一个缓冲区,您必须逐个复制其字符,直到找到0字符(顺便提一下strcpy)。

因此,以下所有行都在argv[1]上运行,因此,如果您要超出其原始范围,任何事情都可能发生。

  

我相信必须有另一种更安全的方法来连接字符串而不使用字符串函数,或者通过复制char并将char附加到新的char数组中。

C字符串只是字符数组,一切都归结为一次复制/读取它们。如果您不想使用提供的字符串函数,您最终将自己重新实现它们。请注意,这是一个有用的练习,但你必须更好地了解C字符串是什么以及指针是如何工作的。

答案 1 :(得分:0)

首先,sizeof(argv [1])不会返回使用loops或使用标准库函数strlen()计算字符串中字符数所需的字符串长度。如果要复制字符串,则需要使用strcpy()函数。

你应该这样做:

unsigned int argsize=strlen(argv[1]);  //you can also count the number of character
unsigned char *newstr=calloc((argsize+5),1);
strcpy(newstr,argv[1]);    
newstr[argsize+4]=oname[ns];    
newstr[argsize]='.'; 
newstr[argsize+1]='X';