为什么传递给函数的数组是null?

时间:2016-08-03 07:49:52

标签: c++

我知道这是基本的,但我从逻辑上考虑了这一点,并且没有得到这个。

char *me[] = {0};
getHardwareEEprom(me);
printf("**%s\n", me[0]); // null 

void EEprom::getHardwareEEprom(char *eeprom[])
{
     char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL};
     eeprom = EEPROM; // set the address for the data array
}
  1. me是一个指向某个地方的指针
  2. 将其传递给此函数,在该函数中获取内存中某个数组的地址
  3. me现在拥有数组EEPROM
  4. 的地址
  5. 打印它的第一个单词show null
  6. 无论我阅读多少,我似乎都没有得到这个东西。

6 个答案:

答案 0 :(得分:7)

这里没什么特别的。

您正在更改函数参数eeprom所分配的内容,即全部。该分配在EEPROM的生命周期内有效。

但是这种变化并没有反映在调用者身上(C ++是一种值传递语言)。因此呼叫者中的me保持不变。

如果引用传递了函数参数eeprom,那将完全不同。

答案 1 :(得分:2)

char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL};具有自动存储,已分配堆栈。

它一直存在,直到函数getHardwareEEprom结束并返回给调用者。

同样char *eeprom[]具有局部范围,因此对函数内部的修改不会反映到传递的指针。

最后,C风格的解决方案可以

#include<stdio.h>

void getHardwareEEprom(char ***eeprom)
{
     static char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL};
     *eeprom = EEPROM; // set the address for the data array
}

int main(void)
{
    size_t i=0;
    char **me = {0};
    getHardwareEEprom(&me);
    while(me[i] != NULL)
    {
        printf("%s\n", me[i]);

        i++;
    }
}

答案 2 :(得分:2)

您正在分配一个局部变量EEPROM,该函数在函数返回时超出范围,因此在您调用printf时它无效。

答案 3 :(得分:1)

参数以C中的值传递。语句

eeprom = EEPROM;

对调用函数没有影响。

答案 4 :(得分:1)

首先,这不是C而是C ++(C没有类,请检查EEprom::)。

另外,请注意变量的范围。这里定义char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL};并在函数内部分配内存,因此当函数返回时,内存将被释放。

这里的另一个问题是你不能在不返回参数的情况下设置参数的地址:当通过引用使用参数时,你的函数会获得指针地址的副本。然后,在您的示例中,您的函数eeprom的本地副本将其地址更改为EEPROM的地址。但是全局副本(用于调用该函数的那个​​)不接受新地址,绕过它,你的函数可以返回正确的地址:

char **foo(void)
{
    char **EEPROM = NULL;
    // Here you should allocate your memory with malloc and fill the array with your data

    return EEPROM;
}

char **bar = foo();

通过这种方式,您可以解决2个问题:不使用指向解除分配内存的指针,并且在函数外部获得指向数据的有效指针。

答案 5 :(得分:1)

当您致电getHardwareEEprom(me);时,您将me的地址传递给该函数,并且您的函数中的eeprom指向该地址。

但是只要你在函数中执行eeprom = EEPROM;,就没有任何连接了。而且,eeprom完全指向其他地方,即它指向EEPROM数组的地址。因此,eepromme不再有任何关系。

要像您期望的那样更改me的内容,您必须执行以下操作:

eeprom[0] = "test"; // OR
*eeprom = "test";