Home > Blockchain >  C segmentation fault when printing different things
C segmentation fault when printing different things

Time:09-26

I am currently making a few functions for a school project. When running each function alone and printing them, I have no errors, however when I print the result of all of the functions in main, I get a segmentation fault for the last function output.

My source code can be found Here. This is the main segment which is not working:

int main() {
    char str1[] = "382 is the best!";
    char str2[100] = {0};

    strcpy(str1, str2);
    puts(str1);
    puts(str2);

    int vec_a[3] = {12,34,10};
    int vec_b[3] = {10,20,30};
    int dot = dot_prod((char*) vec_a, (char*) vec_b, 3, sizeof(int));
    printf("%d\n", dot);
    int arr[3] = {0x12BFDA09, 0x9089CDBA, 0x56788910};
    sort_nib(arr, 3);
    for (int i = 0; i < 3; i  ) {
        printf("0xx ", arr[i]);
    }

    printf("\n");
    return 0;
}

When running this code segment, I get the correct output for all except the final print loop, which I get a segmentation fault. However, if I comment out the puts statements and the printf(dot), the final print loop works.

Any help is greatly appreciated

CodePudding user response:

You have a few problems with your code:

  • Your custom strcpy() function is incorrect since it does not add a NULL terminator to the end of dst. Also the statement dst[i] = src[0]; just copies the 0th element of src to the ith index of dst, which is incorrect. You have also use a goto statement instead of a loop which is confusing. Overall this functions logic is incorrect and makes no sense.

A better implementation would be:

void mystrcpy(char *dest, const char *src)
{
     while (*src) {
            *dest = *src;     // These lines can be
            dest  ;           // Rewritten into one line:
            src  ;            // *dest   = *src  
     }

     *dest = '\0';
}

However you should consider not re-implementing standard library functions at all. This is because your implementation could be unsafe and erroneous (which it is). Furthermore these functions have been written by smart developers and are optimized and well thought out so its better to stick with them.

  • The function dot_prod has a buffer over-read bug. In the following code:
int dot_prod(char* vec_a, char* vec_b, int length, int size_elem)
    PRODLOOP:
        if (i <= (length - 1) * size_elem) {
            int elema = (int) vec_a[i];
            int elemb = (int) vec_b[i];
            product  = elema * elemb;
            i  = size_elem;
            goto PRODLOOP;
        }

This is what you pass to dot_prod() in main():

    int vec_a[3] = {12,34,10};
    int vec_b[3] = {10,20,30};
    int dot = dot_prod((char*) vec_a, (char*) vec_b, 3, sizeof(int));

As a result of this, you are accessing the 0th, 4th, and 8th element of vec_a and vec_b (assuming sizeof(int) is 4). The size of both arrays is 3 so the index range is from 0 to 2.

  • The sort_nib() function invokes undefined behavior in the following code:
char* a[9];
char* s;
int k = 0;

    CONVERT:
        if (k < length) {
            if (k == 0) {
                sprintf((char*) s, "X", arr[k]);
            } else {
                sprintf((char*) a, "X", arr[k]);
                s = combine(s, (char*) a);
            }

s is a uninitialized pointer and a is a array of pointers which are also uninitialized. So calling sprintf() on them invokes undefined behavior since they do not point to anything.

  • Your sort_nib() function uses goto statements instead of loops which is quite confusing.
  • Related