以下是我到目前为止的代码。经过几次迭代后,它会产生分段错误。任何人都可以帮我解决问题吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *str; // 1GB = 1073741824 bytes
char *temp;
long long int i;
str = (char *)malloc(1073741824);
strcpy(str,"a");
for(i = 1; i <= 73741824;i = i*2)
{
strcat(str,str);
}
free(str);
}
答案 0 :(得分:3)
您使用与两个参数相同的字符串调用strcat()
,这是一个错误。见the manual page:
字符串可能不重叠,dest字符串必须有足够的空间用于结果。
答案 1 :(得分:1)
您正在经历一些未定义的行为!如果您阅读strcat
的描述,则会提及:&#34;如果在重叠的对象之间进行复制,则行为未定义,&#34; (source)。
如果你考虑一下,它首先将str
的第一个字节复制到str
的空字节,然后一直持续到空字节。你看到了问题吗?你覆盖它,所以你将继续复制字节,直到遇到垃圾空字节。
解决这个问题的方法是不要使用相同的源和目标字符串。另外,为什么要迭代到73741824?如果你想要一个1GB的字符串,你应该迭代到1073741824.同时请记住,以这种方式构建字符串并不比仅仅连接&#34; a&#34;在你的弦上〜10亿次。知道了,这就是我们最终要解决的问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *str; // 1GB = 1073741824 bytes
char *temp;
long long int i;
const size_t GB = 1073741824;
str = (char *)malloc(GB);
strcpy(str, "a");
for(i = 1; i < GB; i++) {
strcat(str + i, "a");
}
free(str);
}
编辑:如果您更喜欢原始算法,我也已修复此问题。只需进行相应的更改。这样可以避免复制到任何重叠的内存,从而避免任何未定义的行为。
for(i = 1; i < GB; i *= 2) {
str[i - 1] = '\0';
strcat(str + i, str);
str[i - 1] = 'a';
str[2 * i - 1] = 'a';
str[2 * i] = '\0';
}
答案 2 :(得分:0)
我认为这个应该关闭,因为&#34;如果字符串连接到自身会发生什么&#34;问题已经在这里得到解答:Concatenating string with itself two times give segmentation fault。
然而,由于近距离投票被拒绝,还有其他一些问题,我已修复了这些代码。该算法使用2 * SIZE内存,但它明显快于kamoroso94的答案(使用较少的内存)并且更接近问题作者的想法。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE (1024 * 1024 * 1024) // convenient way how to define 1GB
int main()
{
char *str;
char *temp;
long long int i;
// don't forget to allocate space for the terminating character!
str = malloc(SIZE + 1); // no need to typecast the result malloc()
temp = malloc(SIZE + 1);
// don't forget to check for allocation failures
if (str == NULL || temp == NULL) {
printf("malloc failed\n");
return -1;
}
strcpy(temp, "a");
for(i = 1; i <= SIZE; i *= 2) {
// concatenate the buffer to the string
strcat(str, temp);
// copy the whole string to the temporary buffer
strcpy(temp, str);
}
printf("length of s = %u\n", strlen(str));
free(str);
free(temp);
}