在函数之间传递指针后,Char数组被破坏

时间:2017-03-28 07:54:10

标签: c pointers

我已经学习了几个星期的C.我通过使用malloc()在堆上分配一些内存来解决我的问题。我清楚地知道为什么我的代码失败但我不是百分百肯定。不幸的是,我是自学成才,所以我不得不求助于互联网上善良的人。

代码说明调用声明数组的函数getString(),使用内置getchar()填充数组并返回指向该数组的指针。

问题我打印返回的指针值,一切都很好。但是当我将它传递给另一个简单地将其吐出并尝试打印的函数时,字符串的末尾被切断,有时会吐出一个无意义的字符。

我认为可能发生的事情原始数组仅在getString()函数&所以C使用数组地址中的一些内存来存储其他东西。

我的直觉是否正确?如果没有,有人指向我的方向正确吗?

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

#define MAXLEN 100

char * getString(void);
char * doSomethingWith(char *);

int main(void)
{
    char *string1 = getString();
    printf("String: %s\n", string1);
    char *string2 = doSomethingWith(string1);
    printf("String: %s\n", string2); // This print out is unreliable!
    return EXIT_SUCCESS;
}

char * getString(void) {
    int c;
    char arr[MAXLEN];
    char *string = arr;
    char *cur = arr;

    while((c = getchar()) != '\n' && c != EOF) {
        if(cur - string < MAXLEN - 2) {
            *cur++ = c;
        }
    }
    *cur = '\0'; // Terminate string

    return string;
}

char * doSomethingWith(char *string) {
    return string;
}

这是我修正的getString(),它的行为正确。

char * getString(void) {
    int c;
    char *string = malloc(sizeof *string * MAXLEN);
    char *cur = string;

    while((c = getchar()) != '\n' && c != EOF) {
        if(cur - string < MAXLEN - 2) {
            *cur++ = c;
        }
    }
    *cur = '\0'; // Terminate string

    return string;
}

更新:感谢您的所有答案!非常感谢。

2 个答案:

答案 0 :(得分:1)

getString返回具有自动存储持续时间的函数局部变量的地址,地址为arr。在函数返回后通过该地址访问arr的任何尝试都有未定义的行为。

C标准无法保证它会保留其价值。不能保证不会。当你打破像这样的语言约束时,编译器没有义务甚至生成有效的程序。

6.2.4 Storage durations of objects ¶2

  

对象的生命周期是程序执行的一部分,在此期间保证为其保留存储。一个对象存在,具有一个常量地址,33)并在其整个生命周期内保留其最后存储的值.34)如果一个对象在其生命周期之外被引用,则该行为是未定义的。当指针指向(或刚刚过去)的对象到达其生命周期的末尾时,指针的值变得不确定。

上面提到的生命周期是从开始大括号到getString的右大括号,只要它只执行。不多也不少。

答案 1 :(得分:1)

char *string = arr;错误,因为没有arr分配内存;它是堆栈中的变量。返回时,堆栈内存被重新启动,因此您返回一个指向已释放变量的指针。

使用malloc代替,例如:

string= malloc(strlen(arr)+1);
strcpy(string,arr);
return string;