簡體   English   中英

將函數返回的指針設置為某個地址C

[英]Set a pointer returned by a function to some address C

我正在編寫一些C代碼,但遇到以下問題。 假設我們有一個非常簡單的程序:

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

struct this {
    char* str;
};

char* freeStrReturnPointer(struct this * t) {
    free(t->str);
    return t->str;
};

int main() {
    // standard mallocing going on
    struct this* t = malloc(sizeof(struct this));
    t->str = malloc(sizeof(char)*10);
    // here is the problematic part!
    freeStrReturnPointer(t) = NULL;
    // end of problematic part
    free(t);
    exit(0);
}

編譯出現以下問題:

test.c: In function ‘main’:
test.c:18:29: error: lvalue required as left operand of assignment
     freeStrReturnPointer(t) = NULL;

我的問題是:如果函數freeStrReturnPointer返回一個指針char *,為什么不能將其設置為NULL? 以下絕對可以工作:

char* p;
p = NULL;

這里有什么區別? 為什么不能立即為返回的指針分配值?

警告:我意識到我可以在函數中將指針設置為null,但這不是問題的重點。

您不能這樣做,因為表達式freeStrReturnPointer(t)返回一個r值,該值需要分配給一個變量,以便其壽命超出包含它的完整表達式。 實際上,將其分配為“ null”沒有明顯的副作用,並且很可能是程序員的錯誤,因此該語言將其視為錯誤。

相反,你應該做

char * p = freeStrReturnPointer(t);
p = NULL;

然后,在兩個表達式中p都是l值, freeStrReturnPointer(t)在第一個表達式中是r值,而NULL在第二個表達式中是r值。

或者,您可以將freeStrReturnPointer(t)視為void函數,而忽略結果(因為無論如何都不使用它,因此沒有理由將其設置為NULL ):

(void) freeStrReturnPointer(t);

我認為您的意思是返回一個指向該指針的指針,然后取消對該指針的引用並將原始指針設置為NULL

所以在您的代碼中,我會寫:

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

struct this {
    char* str;
};

char** freeStrReturnStrPointer(struct this * t) {
    free(t->str);
    return &t->str;
};

int main(){
    struct this* t = malloc(sizeof(struct this));
    t->str = malloc(sizeof(char)*10);
    *freeStrReturnStrPointer(t) = NULL;
    free(t);
}

釋放后會將str設置為NULL

目前你是剛剛返回的實際指針char ,而不是一個指針指向的存儲char

好吧,您想要做的事情等效於以下內容:

char *p = freeStrReturnPointer(t); 
p = NULL; 

這不會重置t->str 您的freeStrReturnPointer()函數正在返回一個指向字符串的char*值。 如果分配給它,則將覆蓋它指向的位置,從而使它無用的代碼。

如果您這樣做:

char *p = freeStrReturnPointer(t); 
printf("%p\n", t->str);
p = NULL; 
printf("%p\n", t->str);

你會得到:

0x012345678901
0x012345678901

作為輸出。

如果要重置t->str ,則需要使用雙指針:

char** freeStrReturnPointer(struct this * t) {
    free(t->str);
    return &(t->str);
};

在main()中:

char **p = freeStrReturnPointer(t);
printf("%p\n", t->str);
*p = NULL;
printf("%p\n", t->str);

然后將輸出類似:

0x012345678901
0x0

freeStrReturnPointer()返回一個值(更正確的值是正確的值)。 在您的情況下,它是一個指針,但是還是一個值。 正如編譯器告訴您的那樣,您基本上是在嘗試更改=運算符的工作方式。 賦值運算符的左側需要某種變量,而右側則需要一個值(可以再次為變量)。 您在這里的問題不僅限於指針。 甚至嘗試使用基本類型或對象,仍然會出現此錯誤。

似乎在freeStrReturnPointer(struct this * t) ,使用t->str所做的操作與在main中創建的變量無關,並且返回的內容實際上是一個右值(並且不能為右值賦值) 。 我會改用一個指向指針的指針: freeStrReturnPointer(struct this ** t)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM