gcc:为什么两个不同的变量在调用后具有相同的值?

时间:2015-09-16 15:35:33

标签: c function variables gcc

我想知道如何解决这个问题。我承认我在C开始并不是那么棒。我已经对下面的代码进行了评论,以显示正在发生的事情。如果我进行函数调用,则在每次函数调用后立即打印出值,然后结果是正确的。但是,如果我在执行 all 函数调用后打印出值,它只打印出两个变量的 last 值!

为什么要这样做以及如何解决?

注意:我在Linux中使用gcc版本4.9.2(Debian 4.9.2-10)

进行此操作
/* Get first/last of string */

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

void strtoarr(unsigned char *input, int len, unsigned char output[128]);
char* substr(unsigned char input[128], int start_pos, int num_chars);

int main(void)
{

    unsigned char myArr[128];
    unsigned char *myStr = (unsigned char*)"79356e39486a556e576d6c3279443267516834376137333131387246474b3137";
    char *strFirst;
    char *strLast;

    /* For the project I'm working on, I'm going to need this as an array of characters anyway. */
    strtoarr(myStr, 64, myArr);
    printf("Original String: %s\n", myArr);

    printf("\n");

    /* If I print the string after each call, it works.
       Prints out:
       Try 1 First 32: 79356e39486a556e576d6c3279443267
       Try 1 Last 32: 516834376137333131387246474b3137
     */
    strFirst = substr(myArr, 0, 32);
    printf("Try 1 First 32: %s\n", strFirst);
    strLast = substr(myArr, 32, 32);
    printf("Try 1 Last 32: %s\n", strLast);

    printf("\n");

    /* FIXME: Why does it print the exact same thing if I print out after both calls?
       Prints out:
       Try 2 First 32: 516834376137333131387246474b3137
       Try 2 Last 32: 516834376137333131387246474b3137
     */
    strFirst = substr(myArr, 0, 32);
    strLast = substr(myArr, 32, 32);
    printf("Try 2 First 32: %s\n", strFirst);
    printf("Try 2 Last 32: %s\n", strLast);

    return 0;
}

char* substr(unsigned char input[128], int start_pos, int num_chars) {
    char *result = calloc(num_chars * 2 + 1, sizeof(char*));
    int i;

    for(i = start_pos; i < (num_chars + start_pos); i++) {
        result[i - start_pos] = input[i];
    }
    result[(i - start_pos) + 1] = '\0';
    free(result);

    return result;
}


/* Convert string to array of characters */
void strtoarr(unsigned char *input, int len, unsigned char output[128]) {
    int i;

    for(i = 0; i < len + 1; i++) {
        output[i] = input[i];
    }
    output[i + 1] = '\0';
}

2 个答案:

答案 0 :(得分:2)

返回指向释放内存的指针(然后从所述内存中读取)是未定义的行为。

将您的substr更改为不释放内存:

char* substr(unsigned char input[128], int start_pos, int num_chars) {
    char* result = calloc(num_chars + 1, sizeof(char));

    strncpy(result, (char*)input + start_pos, num_chars);

    return result;
}

请记住在呼叫者级别free此内存。

答案 1 :(得分:2)

在你的substr函数中,你可以分配一些内存并复制数据,这很好。但是你释放它然后返回一个指向释放内存的指针。从那时起,使用该指针是未定义的行为!

对于您的实现和在该上下文中引发的内容是两个对malloc的调用返回相同的指针值,这解释了两个指针显示相同的最后一个值。但你也可能有错误或任何其他显示。