Search code examples
clinuxrecursionmemcpy

Serial construction of a string in for-loop with mempcpy leads to endless recursion


The following code snipped is a simplification of code I'm currently working on. It is designed to construct an output string, constructed via a concatenation of strings.

#define _GNU_SOURCE 
#include <argp.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <float.h>
#include <math.h>
#include <string.h>

int main(void) {
    char *english[] = {"zero", "one", "two", "three", "four", "five",
                    "six", "seven", "eight", "nine"};
    char *l_english = malloc(5*sizeof(char)*10+10+1); 
    char *ptr_eng = l_english;   
    for(int i = 0; i<10; i++){
        ptr_eng = mempcpy(ptr_eng,english[i],strlen(english[i]));
        printf("Iteration %d\n",i);
    }
    free(l_english);
    return 0;
}

I am compiling with gcc 4.8.3 under Gentoo Linux. When I run the above program, it does not halt but consumes 100% of a CPU core. Looking at it with gdb, it turns out that the mempcpy goes into endless recursion.

Now on to the things I've already tried:

  1. Unrolling the for-loop. This works perfectly fine if I simply write out the instructions instead of using the for-loop.
  2. Setting a constant size to copy for mempcpy. Yet again, no endless recursion.
  3. Using memcpy and not changing the pointer ´ptr_eng´ inside the loop: Again, no endless recursion.
  4. In relation to 3., using memcpy and setting eng_ptr = eng_ptr+strlen(english[i]). Again, the endless recursion happened.

Sadly, when I Google for memcpy and for-loops, I only find discussions about performance. I am quite the newbie where C is concerned, and I would be grateful for any pointer you can provide.

EDIT

Here is a link to the relevant gdb output http://pastebin.com/nBZhqnsw; this goes on until a segfault occurs.

EDIT 2

To clear things up: The above code is only a simplified example of a program I am currently working on. The formula for the size in the malloc call was actually only a throwaway replacement for a number of variables used to compute the actual amount of memory needed in the real program. The only important thing for this example is that it is enough memory to hold the ten words from the english variable.

The expected result is for l_english to be a pointer to the beginning of a chunk of memory holding "zeroonetwothreefourfivesixseveneightnine". Like I said, it is only a simplification for the sake of Stack Overflow.


Solution

  • Here is the problem: I compiled my code with GCC under Linux with --std=c99. At the link provided by @Joachim Pileborg in his comment to my question, I saw the option --std=gnu99.

    Out of pure despair I tried it...and the program ran smoothly. The compiler obviously did something funny there.

    Thanks to you all for your comments.