为什么指针变量在通过多个函数后发生变化

时间:2017-08-23 07:24:50

标签: c pointers memory

我通过引用将变量传递给函数,然后在该函数中通过指针将变量传递给另一个函数。在最终函数中,变量被赋值给,当我在最终函数中将其打印出来时,它会成功打印。

当我尝试访问外部函数中的变量时,变量已更改。

变量p是最外层函数中的局部变量,我正在传递地址。我不知道变量为什么会改变,因为我传入指针。

这是我的代码的样子。我已经简化了代码,使其更容易理解而无需粘贴太多其他代码。

我将p传递给get_dsp(root, &p)

b_error
run_activate(int argc, char **argv){
    b_error ret = B_SUCCESS;
    char *root = "example_root";

    char *p;

    if ((ret = get_dsp(root, &p)) != B_FAILURE) {
        fprintf(stdout, "run_activate: %s.\n", p);
    }
    return ret;
}

然后我将其传递到get_dsp(...)中的另一个函数。

b_error
get_dsp(char *ds, char **p) {
    handle_t *hdl;
    b_e_t *b_be = NULL;
    b_error ret = B_SUCCESS;

    if((hdl = zl_init()) != NULL) {

        if (zl_get_dsp(hdl, ds, p) != ZL_SUCCESS) {
            fprintf(stderr, "b: Error getting p'\n");
            ret = B_FAILURE;
        }

        zl_fini(hdl);
    } else {
        fprintf(stderr, "b: Error initializing zl\n");
        ret = B_FAILURE;
    }
    fprintf(stdout, "get_dsp: p: %s'\n", *p);
    return ret;
}

在上一个功能zl_get_dsp中,正确打印p

zl_error
zl_get_dsp(handle_t *hdl, const char *ds, char **p){
    z_handle_t *z = NULL;
    zl_error ret = ZL_SUCCESS;

    if (hdl == NULL) {
        fprintf(stderr, "zl: zl isn't initialized\n");
        ret = ZL_FAILURE;
    } else {
        if ((z = z_open(hdl, ds)) == NULL) {
            fprintf(stderr, "zfslib: Failure opening handle to zl '%s'\n", dataset);
            ret = ZL_FAILURE;
        } else {

            if ((*p = get_pn(z)) != NULL){
                fprintf(stdout, "zl_get_dsp: '%s'\n", *p);
            } else {
                fprintf(stderr, "zl: Failure getting pn\n");
                ret = ZL_FAILURE;
            }

            z_close(z);
        }
    }
    return ret;
}

函数get_pn返回一个字符串。

const char *get_pn(z_handle_t *z){
    return (z->zp_hdl->pn);
}

typedef struct z_handle z_handle_t;
typedef struct zp_handle zp_handle_t;

struct z_handle {
    zp_handle_t *zp_hdl;
    // ...
};

struct zp_handle {
    char pn[MAX_LEN];
};

当它返回另外两个函数并尝试打印p时,不会打印任何内容。

这是输出。 p在最后一个函数zl_get_dsp中正确打印一次,但在外两个函数中没有正确打印。

zl_get_dsp: 'v_printed'
get_dsp: p: '
run_activate: .

我尝试动态分配变量,但它没有帮助。我也试过直接传入一个指针,或传入一个变量的地址,它没有任何区别。

我想是因为我在第一个函数中使用了一个局部变量,我的变量不应该自行改变。我会理解,如果我试图返回一个我没有通过的指针,但这不是我正在做的事情。

有什么明显的我做错了吗?

我感到沮丧并且无法使其发挥作用,我看到一篇关于使用strcpy的帖子,我尝试了有效的帖子。

char *temp_p;
// ...
if ((temp_p = get_pn(zhp)) != NULL){
// ...
strcpy(*p,temp_p);

这是因为我指向的变量正在以某种方式被另一个函数改变吗?当我使用strcpy时,它会复制它,所以另一个变量的变化并不重要吗?

2 个答案:

答案 0 :(得分:0)

  

为什么指针变量在传递多个后会发生变化   功能

如果你不修改内容(它可能是一个指向同一块内存的指针)或指针指向它自己的位置,它就不能。

  

我通过引用传递变量

来自www-cs-students.stanford.edu

的C语言无法实现
  

在C中,通过传递a的地址来模拟传递引用   变量(指针)并取消引用该地址   用于读取或写入实际变量的函数。这将被提及   as" C style pass-by-reference。"

请看下面的示例,我们正在通过各种函数传递指针,但指针地址和内容仍然相同。

void f3(char **p)
{
    printf("f3: Address: %p, Value: %s\n", *p, *p);
}

void f2(char **p)
{
    printf("f2: Address: %p, Value: %s\n", *p, *p);
    f3(p);
}

void f1(char **p)
{
    printf("f1: Address: %p, Value: %s\n", *p, *p);
    f2(p);
}

int main(void)
{
    char *p = malloc((int)strlen("hello"));
    strcpy(p, "hello");

    printf("Main 1: Address: %p, Value: %s\n", p, p);

    f1(&p);

    printf("Main 2: Address: %p, Value: %s\n", p, p);

    return 0;
}

<强>输出

Main 1: Address: 0x1a7c010, Value: hello
f1    : Address: 0x1a7c010, Value: hello
f2    : Address: 0x1a7c010, Value: hello
f3    : Address: 0x1a7c010, Value: hello
Main 2: Address: 0x1a7c010, Value: hello

看看这里(zl_get_dsp函数内部)

z_handle_t *z = NULL;

您已创建包含数组z的本地变量pn。在这里,您将一些字符串分配给pn内的z

z = z_open(hdl, ds)

然后,如果你在同一个函数中打印它,一切正常,字符串显示

fprintf(stdout, "zl_get_dsp: '%s'\n", *p)

但是在返回上一个函数之后,z超出范围,这意味着数组pn也不在范围内,而pn内的字符串不再存在,如果你是试图用另一种功能打印他。如果你想返回指向 cant 是本地的东西的指针,因为从函数返回后它超出了范围,所以你必须将z声明为全局或给他一些动态内存{ {1}}。

答案 1 :(得分:-1)

如果在传递参考后,您访问变量并查找更改了变量中记忆的值,然后在代码中的某个位置将该值赋给该指针