使用mempcpy在for循环中串行构造字符串会导致无休止的递归

时间:2014-08-12 11:12:58

标签: c linux recursion memcpy

以下代码剪切是我正在处理的代码的简化。它旨在构造一个输出字符串,通过串联串联构造。

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

我正在使用Gentoo Linux下的gcc 4.8.3进行编译。当我运行上面的程序时,它不会停止但消耗100%的CPU核心。用gdb来看,mempcpy进入无限递归。

现在我已经尝试过的事情了:

  1. 展开for循环。如果我只是写出指令而不是使用for-loop,那么这种方法非常好。
  2. 设置常量大小以复制mempcpy。再一次,没有无尽的递归。
  3. 使用memcpy而不是在循环中更改指针'ptr_eng':再次,没有无休止的递归。
  4. 关于3.,使用memcpy并设置eng_ptr = eng_ptr+strlen(english[i])。再一次,无休止的递归发生了。
  5. 可悲的是,当我使用Google memcpy和for循环时,我只会找到有关性能的讨论。我很关注C的新手,我很感激你能提供的任何指针。

    修改

    以下是相关gdb输出http://pastebin.com/nBZhqnsw的链接;这种情况一直持续到发生段错误。

    编辑2

    要清理:上面的代码只是我目前正在处理的程序的简化示例。 malloc调用中的大小公式实际上只是用于计算实际程序中所需的实际内存量的许多变量的一次性替换。对于这个例子来说,唯一重要的是它有足够的内存来容纳english变量中的十个单词。

    预期的结果是l_english是一个指向“zeroonetwothreefourfivesixseveneightnine”的内存块开头的指针。就像我说的那样,它只是为了Stack Overflow而进行的简化。

2 个答案:

答案 0 :(得分:2)

我不知道为什么它不起作用,所以我建议你保持程序简单,一切都会顺利进行:

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

int main(void) {
    const char* english[] = 
    {
      "zero", 
      "one", 
      "two", 
      "three", 
      "four", 
      "five",
      "six", 
      "seven", 
      "eight", 
      "nine"
    };

    char *l_english = malloc(5*sizeof(char)*10+1); // 5 chars times 10 plus nul
    char *ptr_eng = l_english;   
    for(size_t i=0; i<10; i++)
    {
        const char* ptr_ch = english[i];

        while(*ptr_ch != '\0')
        {
            *ptr_eng = *ptr_ch;
            ptr_eng++;
            ptr_ch++;
        }

        printf("Iteration %d\n",i);
    }
    *ptr_eng = '\0';   

    puts(l_english);

    free(l_english);
    return 0;
}

输出:

Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
Iteration 6
Iteration 7
Iteration 8
Iteration 9
zeroonetwothreefourfivesixseveneightnine

此外,上面的while循环比memcpy + strlen更有效。

答案 1 :(得分:0)

问题在于:我使用-std = c99在Linux下使用GCC编译了我的代码。在@Joachim Pileborg在我的问题评论中提供的链接中,我看到了选项--std = gnu99。

出于纯粹的绝望,我尝试了......程序运行顺利。编译器显然在那里做了一些有趣的事情。

感谢大家的评论。