2010-03-29 36 views
15

Hôm qua trong cuộc phỏng vấn của tôi, tôi đã được hỏi câu hỏi này. (Vào thời điểm đó tôi bị áp lực cao bởi rất nhiều câu hỏi đột ngột).Có vấn đề với int * p; * p = 23;

int *p; 
*p=23; 
printf("%d",*p); 

Có vấn đề gì với mã này không?

Tôi đã giải thích rằng bạn đang cố gán giá trị cho con trỏ mà bộ nhớ không được cấp phát.

Nhưng cách anh ấy phản ứng, nó giống như tôi sai. Mặc dù tôi đã nhận được công việc nhưng sau đó anh ấy nói Mohit nghĩ về câu hỏi này một lần nữa. Tôi không biết anh ta đang cố nói gì. Xin vui lòng cho tôi biết là có bất kỳ vấn đề trong câu trả lời của tôi?

EDIT tôi thêm mã trên bảng; -

int *p; 
p=malloc(sizeof(int)); 
*p=23; 
printf("%d",*p);  

này phải được mã hoàn hảo ... Am i right ..

EDIT2

int *p; 
*p=23; 
OR 
int *p=23; 

Tôi nghĩ cả hai đều có vấn đề. Nguyên nhân một số cơ thể nói về tiêu đề của bài viết.

+4

Câu hỏi hay. Và người phỏng vấn có quyền hỏi những câu hỏi như vậy. Họ rõ ràng cho thấy những gì "năm năm phát triển C" của một người có giá trị. – sharptooth

+4

Xin lưu ý tiêu đề câu hỏi của bạn và văn bản câu hỏi của bạn khác nhau về mặt ngữ nghĩa. –

+0

Cố định tiêu đề cho những gì (tôi nghĩ) dự định – Yacoby

Trả lời

28

"cố gắng chỉ định giá trị cho con trỏ mà bộ nhớ không được phân bổ"

Tôi nghĩ bạn đã làm sai lệch nó một chút. Bạn không cố gán giá trị cho con trỏ, bạn đang cố chỉ định giá trị cho tham chiếu của con trỏ.

Vì con trỏ chưa được khởi tạo, điều này giống như bạn nói, hành vi không xác định. Con trỏ không đề cập đến bất cứ điều gì (ít nhất là không hợp lệ - như các câu trả lời khác chỉ ra, các bit lưu trữ p có thể xảy ra để chứa giá trị là địa chỉ của một số vị trí bộ nhớ và mã của bạn có thể ghi đè lên. Tiêu chuẩn cho phép bất cứ điều gì xảy ra với UB, nhưng biết một cái gì đó về việc thực hiện của bạn, bạn thường có thể đoán một cách khôn ngoan). Vì vậy, có lẽ trong tâm trí của người phỏng vấn bạn có ý tưởng đúng, nhưng nó có giá trị để có nó chính xác trong tâm trí của bạn và trong bài phát biểu của bạn những gì là sự khác biệt giữa một ngón tay và mặt trăng, và cái nào bạn đang nói về .

+0

yaa tôi giải thích anh ta một cách thích hợp rằng một hành vi không xác định của nó gây ra con trỏ không có bất kỳ bộ nhớ và không phân bổ bộ nhớ u r gán giá trị cho bộ nhớ un initialized. Tôi chỉ muốn xác nhận logic là đúng .. Hoặc os ansswer của tôi hoàn toàn sai. –

+14

Không, bạn cũng không phải là "gán giá trị cho bộ nhớ chưa được khởi tạo". Nếu tôi cung cấp cho bạn một phong bì để cung cấp, và địa chỉ (giá trị con trỏ) là smudged (uninitialised), sau đó bạn không thể cung cấp nó. Tuy nhiên, bạn không cố gắng phân phối nó tới một ngôi nhà * nhòe *, bạn đang cố gắng tìm ra ngôi nhà nào có phong bì * nhòe *. Nó không đề cập đến bất kỳ ngôi nhà nào, vì vậy bạn có thể nghỉ ngơi vào buổi chiều (hành vi không xác định). –

+3

Vì vậy, ví dụ nếu tôi viết 'char c; char * p = & c; * p = 'X'; ', sau đó tôi gán một giá trị ('X') cho bộ nhớ chưa được khởi tạo (biến' c'). Không có gì sai với điều đó. –

14

p không được khởi tạo - nó lưu trữ một số địa chỉ. Dereferencing nó là hành vi không xác định.

Địa chỉ được lưu trữ trong p có thể được ánh xạ vào không gian địa chỉ của quy trình hoặc có thể không được ánh xạ. Nếu nó được ánh xạ một số dữ liệu không liên quan (nhưng có thể quan trọng đối với chương trình) được lưu trữ tại địa chỉ đó. Vì vậy, hoặc chương trình của bạn bị treo ngay lập tức vì bảo vệ bộ nhớ hoặc bạn thay đổi một số dữ liệu thuộc chương trình. Hậu quả của việc này có thể thay đổi - có thể không có gì xảy ra, có thể bạn không nhận thấy, có thể bạn đã làm hỏng dữ liệu quan trọng và chương trình bị phá vỡ - hành vi không xác định cổ điển.

7

'p' đang trỏ đến vị trí không xác định và không trỏ đến bộ nhớ "không được phân bổ".

Sự khác biệt là vì nó không được xác định, nó có thể trỏ đến bộ nhớ được cấp phát, ngay cả khi bộ nhớ này không được truy cập bởi hàm này.

2

int * p;

initailly con trỏ trên chứa một số giá trị rác (giá trị địa chỉ không hợp lệ hoặc địa chỉ chưa được phân bổ).

* p = 23;

thì bạn đang cố gắng đặt một số giá trị (23) vào bộ nhớ không hợp lệ dẫn đến hành vi không xác định.

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

int main(char** argv) { 
    // THIS POINTER IS NOT DECLARED (SO IT'S NOT USABLE/INVALID) 
    int *p; 
    // 1) SO RESERVE MEMORY AND SET POINTER TO VALID MEMORY... 
    p=malloc(sizeof(int)); 
    // 2) ...CHECK IF ALLOCATION WAS OK... 
    if (p) { 
    *p=23; 
    printf("%d",*p); 
    } else printf("sorry, no memory"); 
    // 3) ...AND FINALLY DE-ALLOCATE MEMORY (FREEING IS IGNORED WHEN p IS NULL)! 
    free(p); 
} 
+1

Và kiểm tra giá trị trả về của 'malloc' cho null. –

+1

Tôi nghĩ * p = 23; nên xảy ra sau khi kiểm tra phân bổ được thực hiện. – Brian

+0

Đừng gọi 'free()' trừ khi 'malloc()' đã thành công. Cuộc gọi đó sẽ ngay lập tức theo 'printf()', bên trong 'if'. –

0

Ngoài thực tế là ví dụ không phân bổ bộ nhớ cho giá trị 23, nó cũng sẽ không biên dịch ở vị trí đầu tiên vì bạn có hai ký tự trong hằng số characted của bạn (có nghĩa là là một chuỗi). Ví dụ, thay thế '% d' bằng "% d" trong câu lệnh printf.

+0

@Jasper Bekkers Yupp. –

3

int * p = 23;

Điều này hoàn toàn khác. Ở đây bạn đang khai báo một con trỏ và gán cho nó một giá trị là 23. Nghĩa là nó trỏ đến vị trí bộ nhớ 23, có thể hoặc không thể chứa dữ liệu có thể đọc được.

Nhưng chỉ cần chỉ định một giá trị tùy ý cho một con trỏ mà không có dereferencing nó là hoàn toàn an toàn.

Các vấn đề liên quan