我试图通过连接C中的字符串来生成1 GB的数据

时间:2018-02-12 12:31:51

标签: c

以下是我到目前为止的代码。经过几次迭代后,它会产生分段错误。任何人都可以帮我解决问题吗?

#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);
}

3 个答案:

答案 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);
}