我可以知道传递给函数内函数的本地数组吗?

时间:2016-09-23 10:28:06

标签: c arrays

我收到了以下的写入访问冲突:

void fun
    (
    char** s,
    //EDIT_START
    bool resize = false
    //EDIT_END
    )
{
    //EDIT_START
    if(resize)
        *s = (char*)calloc(20, 1);
    //EDIT_END
    (*s)[0]='a';
}

int main(void) 
{
    char f1[10];
    char* f2 = (char*)calloc(10, 1);
    fun((char**)&f1);
    fun(&f2);
    return 0;
}

罪魁祸首

fun((char**)&f1);

我在这里缺少什么?

3 个答案:

答案 0 :(得分:5)

数组不是指针。 2D数组不是指针指针。

有一条规则说,当在表达式中使用数组时,“衰变”为指向第一个元素的指针。这是数组和指针之间的唯一关系。

你可以在指针上使用[]运算符来赋予它类似数组的行为这一事实并不能使它成为一个数组。

&f1为您提供数组的地址。它的类型是指向数组的指针,类型为char(*)[10]数组指针。这是一种不同的指针类型,与char*char**不兼容。你有想法使用char**,我不知道。忘记将char**与数组一起使用。 See this

您的代码应该写成:

void fun(char* s)  // or char s[], doesn't matter
{
    s[0]='a';
}

int main(void) 
{
    char f1[10];
    char* f2 = calloc(10, 1);
    fun(f1);
    fun(f2);
    return 0;
}

答案 1 :(得分:2)

删除演员表并打开警告,编译器会告诉你错误:

a.c: In function 'main':
a.c:13: warning: passing argument 1 of 'fun' from incompatible pointer type
a.c:4: note: expected 'char **' but argument is of type 'char (*)[10]'

关键信息是:expected 'char **' but argument is of type 'char (*)[10]'。该函数需要一个指向指针的指针,该指针与指向数组的指针不同。

我确定你知道数组在传递给函数时会衰减为指针。 但是,指向数组的指针不会衰减!

如果你有

char arr[10];
char *p;

然后p是左值,而arr则不是。左值可以在作业的左侧:

p = arr;   // OK
arr = p;   // Error: arr is not an lvalue!

答案 2 :(得分:-1)

谢谢大家的答案和时间。我提出了一种方法,并将自己回答这个问题以供自我参考。

void f(char** c1, bool resize)
{
    void* v1 = (void*)(*c1);
    cout << "changing memory at "<<v1<<"\n";

    if(resize)
        resize(c1); //defined elsewhere

    (*c1)[0]='a';
    (*c1)[0]='b';
    (*c1)[0]='c';
    (*c1)[0]='\0';
}

int
main
        (
        int argc,
        char *argv[]
        )
{

    char* s2 = (char*)calloc(4, 1);

    char s3[4];
    char* ps3 = s3;

    cout << "passing memory location ["<<(void*)&s2<<"] pointing to ["<<(void*)s2<<"]\n";
    f(&s2, true);
    cout << "passing memory location ["<<(void*)&s3<<"] pointing to ["<<(void*)s3<<"]\n";
    f((char**)&s3, false);
    cout << "passing memory location ["<<(void*)&ps3<<"] pointing to ["<<(void*)ps3<<"]\n";
    f((char**)&ps3, false);
}

输出:

passing memory location [006CFA20] pointing to [0076EAF0]
changing memory at 0076EAF0
passing memory location [006CFA18] pointing to [006CFA18]
changing memory at 006CFA80
passing memory location [006CFA1C] pointing to [006CFA18]
changing memory at 006CFA18

原来s3 == &s3。不知道那个。我想,生活和学习。