【问题标题】:gcc: Why does two different variables have the same value after call?gcc:为什么两个不同的变量在调用后具有相同的值?
【发布时间】:2015-09-16 15:35:33
【问题描述】:

我想知道如何解决这个问题。我承认我一开始就不太擅长 C。我已经评论了下面的代码以显示正在发生的事情。如果我进行函数调用,然后在每次函数调用后立即打印出值,那么结果是正确的。但是,如果我在执行 all 函数调用后打印出值,它只会打印出 both 变量的 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';
}

【问题讨论】:

  • 你的 substr 返回释放的内存 -> 这是未定义的行为
  • 注意:void strtoarr(... unsigned char output[128] 等价于unsigned char * outputoutput 是指针而不是数组。 substr(... 中的 input 相同。

标签: c function variables gcc


【解决方案1】:

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

更改您的 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这个内存。

【讨论】:

  • 所以在调用者函数中我在 return 0 部分之前做了一个 free(strFirst) 和 free(strLast) 并删除了 free(result);来自 substr 函数。那行得通!谢谢!
  • 经验法则:对于每个 alloc,都应该有一个 free。你在哪里处理,这取决于你。
【解决方案2】:

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

幕后发生的事情对于您的实现以及在该上下文中,两个对 malloc 的调用都返回了相同的指针值,这解释了两个指针显示相同的最后一个值。但您也可能遇到错误或任何其他显示。

【讨论】:

    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2017-01-04
    • 2011-09-20
    相关资源
    最近更新 更多