Khi bạn viết một "chuỗi" trong mã nguồn của mình, nó sẽ được ghi trực tiếp vào tệp thực thi vì giá trị đó cần được biết tại thời điểm biên dịch (có sẵn các công cụ để tách phần mềm ra và tìm tất cả các chuỗi văn bản thuần túy trong đó). Khi bạn viết char *a = "This is a string"
, vị trí của "Đây là một chuỗi" nằm trong tệp thực thi và vị trí a
trỏ đến, nằm trong tệp thực thi. Dữ liệu trong hình ảnh thực thi ở chế độ chỉ đọc.
Những gì bạn cần làm (như các câu trả lời khác đã chỉ ra) là tạo bộ nhớ đó ở một vị trí không chỉ được đọc - trên heap hoặc trong khung ngăn xếp. Nếu bạn khai báo một mảng cục bộ, thì không gian được tạo trên ngăn xếp cho mỗi phần tử của mảng đó và chuỗi ký tự (được lưu trữ trong tệp thực thi) được sao chép vào không gian đó trong ngăn xếp.
char a[] = "This is a string";
bạn cũng có thể sao chép dữ liệu đó theo cách thủ công bằng cách phân bổ một số bộ nhớ trên heap, sau đó sử dụng strcpy()
để sao chép một chuỗi ký tự vào không gian đó.
char *a = malloc(256);
strcpy(a, "This is a string");
Bất cứ khi nào bạn phân bổ không gian bằng cách sử dụng malloc()
nhớ gọi free()
khi bạn hoàn thành nó (đọc: rò rỉ bộ nhớ).
Về cơ bản, bạn phải theo dõi xem dữ liệu của mình đang ở đâu. Bất cứ khi nào bạn viết một chuỗi trong nguồn của mình, chuỗi đó chỉ được đọc (nếu không, bạn sẽ có khả năng thay đổi hành vi của tệp thực thi - hãy tưởng tượng nếu bạn đã viết char *a = "hello";
và sau đó đổi a[0]
thành 'c'
. Sau đó, ở một nơi khác đã viết printf("hello");
. Nếu bạn được phép thay đổi ký tự của "hello"
và trình biên dịch của bạn chỉ lưu trữ nó một lần (nó nên), sau đó printf("hello");
sẽ xuất ra cello
!)