2011-02-04 49 views
6

Tôi đã cố gắng tìm kiếm lý do tại sao mã sau bị lỗi và tôi không thể tìm thấy mã. Vì vậy, xin vui lòng, xin lỗi sự thiếu hiểu biết của tôi và cho tôi biết những gì đang xảy ra ở đây.Char * p và scanf

#include<stdio.h> 
int main(void){ 
char* p="Hi, this is not going to work"; 
scanf("%s",p); 
return 0; 
} 

Theo như tôi đã hiểu, tôi đã tạo con trỏ tới vùng tiếp giáp trong bộ nhớ có kích thước 29 + 1 (cho \ 0). Tại sao tôi không thể sử dụng scanf để thay đổi nội dung đó?

P.S Vui lòng sửa tôi Nếu tôi nói gì đó sai về char *.

Trả lời

14
char* p="Hi, this is not going to work"; 

này không cấp phát bộ nhớ để bạn có thể viết

điều này tạo ra một String Literal mà kết quả trong Undefined Behaviour mỗi khi bạn cố gắng thay đổi nội dung của nó.

sử dụng p như một bộ đệm cho scanf bạn làm điều gì đó như char * p = malloc(sizeof(char) * 128); // 128 is an Example

HOẶC

bạn cũng có thể làm:

char p[]="Hi, this is not going to work"; 

Mà tôi đoán là những gì bạn thực sự muốn làm .

Hãy nhớ rằng điều này vẫn có thể kết thúc là UBscanf() không kiểm tra xem địa điểm bạn đang sử dụng có thực sự là bộ nhớ có thể ghi hợp lệ hay không.

nhớ:

char * p là một String Literal và không nên được sửa đổi

char p[] = "..." phân bổ đủ bộ nhớ để giữ chuỗi bên trong "..." và có thể được thay đổi (nội dung của nó có nghĩa là tôi).

Edit:

Một thủ thuật tốt đẹp để tránh UB

char * p = malloc(sizeof(char) * 128); 
scanf("%126s",s); 
+0

Nếu đó là trường hợp, sau đó làm thế nào để đọc một chuỗi có chiều dài không xác định? – Fingolfin

+0

@Adel, chỉnh sửa nhỏ, nhìn dòng cuối cùng – Muggen

+0

Thật tuyệt, cảm ơn! Nhưng, phải làm gì nếu tôi không thể dự đoán độ dài của chuỗi được quét? – Fingolfin

-3

scanf() phân tích dữ liệu được nhập từ stdin (thông thường, bàn phím). Tôi nghĩ bạn muốn sscanf().

Tuy nhiên, mục đích của scanf() là một phần chuỗi có chuỗi thoát được xác định trước mà chuỗi thử nghiệm của bạn không có. Vì vậy, làm cho nó một chút không rõ ràng chính xác những gì bạn đang cố gắng để làm.

Lưu ý rằng sscanf() lấy một đối số bổ sung làm đối số đầu tiên, xác định chuỗi được phân tích cú pháp.

+0

Tôi nghĩ rằng câu hỏi là tại sao scanf không hoạt động. Trả lời bởi Muggen giải thích rằng – user210504

+0

Tôi thấy một số điều sai trái với mã của OP, do đó, có một chút khó khăn để biết chính xác những gì ông đã cố gắng để thực hiện. –

6

p trỏ đến một hằng số theo nghĩa đen, thực tế có thể nằm trong vùng bộ nhớ chỉ đọc (phụ thuộc thực hiện). Ở bất kỳ tỷ lệ nào, cố gắng ghi đè lên đó là hành vi không xác định. I E. nó có thể dẫn đến không có gì, hoặc một vụ tai nạn ngay lập tức, hoặc một tham nhũng bộ nhớ ẩn gây ra những vấn đề bí ẩn sau này. Đừng bao giờ làm điều đó.

+1

@Downvoter, quan tâm giải thích? –

+0

@Peter, tôi đã không downvote nhưng không thấy một lý do là tại sao -1 vì vậy tôi +1 – Muggen

+0

Tôi chỉ cần bỏ phiếu bầu của tôi xuống. Tôi đã thấy một số lời giải thích khác trước đó. Tôi đoán bạn đã chỉnh sửa điều này. – user210504

0

Người ta đâm vì bộ nhớ chưa được phân bổ cho p. Phân bổ bộ nhớ cho p và nó sẽ là ok. Những gì bạn có là một khu vực bộ nhớ liên tục trỏ đến bởi p. Khi bạn cố gắng viết một cái gì đó trong phân đoạn dữ liệu này, môi trường thời gian chạy sẽ nâng một cái bẫy sẽ dẫn đến sự cố.

Hy vọng điều này sẽ trả lời câu hỏi của bạn