hatake kakashi
hatake kakashi

Reputation: 35

Segmentation fault on copying string elements to another string

Why am I getting segmentation fault? I have listed my code below.

Please tell if anyone knows what is my fault here and how do I correct it?

What I am trying to do here

I am trying to take numbers as input and for them I have to output a string of characters.

Problem

link to the problem is here.

The code of my proposed solution

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

Upvotes: 0

Views: 102

Answers (4)

yakobyd
yakobyd

Reputation: 582

Short Answer: The segmentation fault is caused by char l[10000000];. Decalring char l[26]; is sufficient.

Details

As others said the allocation char l[10000000]; causes the segmentation fault. You do not need this much memory. The question stated that the maximum value for n is 10^18. Thus the maximum length of a word would be 26 characters. Thus, char l[26]; is sufficient.

Explanation: It is given that you have 10^18 options to arrange k characters. Each charater has 5 options and thus the number of options to arrange these characters is 5^k. Now, you just have to find k:

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

Implementation

Regarding the implementation, you have few wrong things going on.

  • You do not set i = 0; after each input scan.
  • Your can not use strlen without the terminating null-character. You should add l[i] = '\0'; above p = strlen(l);.
  • Your second for loop, the one that should revert the string, is not working properly. Each step changes the string and the steps after it use the changed string (instead of working with the original one).

Regarding the algorithm, it does not work properly as well. I can give you a hint: this problem is similar to counting in base-5.

Comments

The things above are just few things that I have noticed. I think you should consider rewriting the code since it may still contaion small flaws.

Another tip: for printing strings (character arrays in c) you can use

printf("%s", str);

Assuming that str is an array of character that ends with the terminating null-character. Some more information here.

Upvotes: 0

H.S.
H.S.

Reputation: 12679

char l[10000000];

This huge array is overflowing your stack memory.
The stack memory segment is an area of memory allotted for automatic variables and its size is fairly small. It is not a good idea to have such a huge array in stack. Try to allocate it dynamically, like this:

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

With this, the memory allocated to l in heap segment. Make sure to free it once you done with it.

Alternatively, you can make l a global variable or a static local variable so that it will go in Data Segment.

Upvotes: 2

Achal
Achal

Reputation: 11921

Firstly, initialize the variable i after scanning n.

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

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

Also instead of creating stack created array like char l[10000000]; create the dynamic array once before while loop and free the dynamically allocated memory once done. for e.g

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

Upvotes: 0

jme52
jme52

Reputation: 1123

You are getting a segmentation fault when you start running your binary because you are running out of stack memory due to the big size of your array char l[10000000] (you can check the size of your stack by running

$ ulimit -s

in your shell).

There are at least two solutions to this:

  1. Increase the size of your stack. You can do this by running, e.g.,

    $ ulimit -s unlimited
    

    in your shell before running the binary.

  2. Use malloc to allocate the l array, so that it is allocated in the heap rather than in the stack.

Upvotes: 0

Related Questions