将字符串元素复制到另一个字符串时出现分段错误

时间:2018-06-23 12:09:53

标签: c segmentation-fault

为什么我会遇到细分错误?我在下面列出了我的代码。

请告诉是否有人知道我的错在哪里,我该如何纠正?

我要在这里做什么

我正在尝试将数字作为输入,为此我必须输出一个字符串。

问题

link to the problem is here.

我建议的解决方案的代码

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

int main() {

    long long int n, k;
    char manku[] = { 'm', 'a', 'n', 'k', 'u' };
    char l[10000000];
    int t, i = 0, j, p;
    scanf("%d", &t);

    while (t > 0)
    {
        scanf("%lld", &n);

        while (n > 0)
        {
            j = n % 5;
            if (j == 0)
                l[i] = manku[4];
            else
                l[i] = manku[j - 1];

            n = n / 5;
            i++;
        }

        p = strlen(l);

        for (i = 0; i < p; i++)
            l[i] = l[p - 1 - i];

        for (i = 0; i < p; i++)
            printf("%c", l[i]);

        t--;
    }

    return 0;
}

4 个答案:

答案 0 :(得分:2)

char l[10000000];

这个巨大的数组溢出了堆栈内存。
堆栈内存段是分配给自动变量的内存区域,其大小很小。拥有如此庞大的数组并不是一个好主意。 尝试动态分配它,如下所示:

char *l;
l = malloc(10000000);  //note: size of char is 1

这样,将内存分配给堆段中的l。完成操作后,请确保free

或者,您可以将l设为全局变量或静态局部变量,以便将其放入Data Segment

答案 1 :(得分:0)

首先,在扫描i之后初始化变量n

while(t>0) {
    scanf("%lld",&n);
    i = 0; /* initialize i every time here */

    while(n>0) {
       /* some code */
    }
}

也不要像创建char l[10000000];这样的堆栈创建数组,而是在while循环之前创建动态数组,并在完成free动态分配内存之后创建动态数组。例如

char *l = malloc(SIZE); /* define the SIZE */
...
...
free(l);

答案 2 :(得分:0)

开始运行二进制文件时,您会遇到分段错误,因为数组char l[10000000]的大容量使堆栈内存不足(您可以通过运行检查堆栈的大小

$ ulimit -s

在您的外壳中)。

对此至少有两种解决方案:

  1. 增加堆栈的大小。您可以通过运行例如

    $ ulimit -s unlimited
    
    在运行二进制文件之前,先在您的外壳程序中

  2. 使用malloc分配l数组,以便将其分配在堆中而不是在堆栈中。

答案 3 :(得分:0)

简短回答::分段错误是由char l[10000000];引起的。修饰char l[26];就足够了。

详细信息

正如其他人所说,分配char l[10000000];导致分段错误。您不需要这么多的内存。该问题表明n的最大值为10 ^ 18。因此,一个单词的最大长度为26个字符。因此,char l[26];就足够了。

说明:假设您有10 ^ 18个选项来排列k个字符。每个字符都有5个选项,因此排列这些字符的选项数为5^k。现在,您只需要找到k

5^k = 10^18  ==>  k = log_5(10^18) ~= 25.75218 < 26 

实施

关于实现,您遇到的错误很少。

  • 您无需在每次输入扫描后设置i = 0;
  • 如果没有终止的空字符,则不能使用strlen。您应在l[i] = '\0';上方添加p = strlen(l);
  • 您的第二个for循环(应还原字符串的循环)无法正常工作。每一步都会更改字符串,并在使用更改后的字符串后再执行步骤(而不是使用原始字符串)。

关于算法,它也无法正常工作。我可以给你一个提示:这个问题类似于base-5中的计数。

评论

以上只是我注意到的几件事。我认为您应该考虑重写代码,因为它可能仍然会污染一些小缺陷。

另一个提示:要打印字符串(c中的字符数组),可以使用

printf("%s", str);

假定str是一个以终止的空字符结尾的字符数组。更多信息here