2008-09-09 33 views

Trả lời

31

Không. Bạn chỉ cần tự giải phóng các chuỗi khi bạn tự phân bổ bộ nhớ bằng cách sử dụng chức năng malloc (trong C) hoặc toán tử new (trong C++). Nếu bạn không sử dụng malloc hoặc new, thì char* hoặc chuỗi sẽ được tạo trên ngăn xếp hoặc dưới dạng hằng số biên dịch.

1

Bạn không biết nơi lưu trữ chuỗi ký tự. Nó thậm chí có thể được bộ nhớ chỉ đọc, do đó, mã của bạn nên đọc:

const char* c = "string"; 

Và một mới mảng char nên xóa d giống như bất kỳ khu vực bộ nhớ được cấp phát động khác.

4

Chúng không giống nhau. Ví dụ đầu tiên của bạn là một chuỗi không đổi, do đó, nó chắc chắn không được cấp phát từ heap. Ví dụ thứ hai của bạn là phân bổ bộ nhớ thời gian chạy gồm 6 ký tự và xuất phát từ vùng heap. Bạn không muốn xóa ví dụ đầu tiên của mình, nhưng bạn cần phải delete [] ví dụ thứ hai của mình.

+1

"mới" cấp phát bộ nhớ từ heap, không bao giờ từ ngăn xếp. (Trừ khi, tất nhiên, bạn đã ghi đè toán tử mới.) –

+0

Tệ của tôi. Tôi biết rằng. Có thật không. :-) – Andrew

+0

Sau đó vui lòng chỉnh sửa;) – FordFulkerson

4

Tôi giả sử khi tôi làm char* = "string" điều tương tự như char* = new char[6].

No. Điều đầu tiên tạo ra hằng số. Sửa đổi nó là hành vi không xác định. Nhưng để trả lời câu hỏi của bạn; không, bạn không phải tiêu diệt chúng. Và chỉ một ghi chú, luôn sử dụng std::string bất cứ khi nào có thể.

0

mới luôn là phân bổ trong khi xác định chuỗi nội tuyến thực sự nhúng dữ liệu vào chương trình và không thể thay đổi (một số trình biên dịch cho phép điều này bằng mẹo thông minh, đừng bận tâm).

Một số trình biên dịch loại chuỗi nội tuyến để bạn không thể sửa đổi bộ đệm.

char* const sz1 = "string"; // embedded string, immutable buffer 
char* sz2 = new char[10]; // allocated string, should be deleted 
17

số Khi bạn nói:

const char* c = "Hello World!"; 

Bạn đang chuyển nhượng c thành một chuỗi "tồn tại trước đó" liên tục mà không phải là giống như:

char* c = new char[6]; 

Chỉ trong trường hợp thứ hai là bạn phân bổ bộ nhớ trên heap. Vì vậy, bạn sẽ gọi xóa khi bạn hoàn tất.

3

Tên của trò chơi là "chỉ tiêu diệt những gì bạn đã tạo".Dưới đây là các cặp:

  1. malloc/free
  2. calloc/free
  3. new/delete
  4. new []/delete []

Vì bạn tạo ra chuỗi thứ 2 sử dụng new [], nhiệm vụ là để bạn phá hủy nó với delete []. Hãy gọi delete [] string2 khi bạn hoàn tất.

Bây giờ, nếu mã của bạn đủ phức tạp và giúp việc theo dõi việc xóa khó khăn, hãy xem xét việc sử dụng con trỏ phạm vi hoặc con trỏ tự động. Lớp học boost::scoped_ptr từ thư viện tăng cường là một nơi tốt để bắt đầu. Ngoài ra, hãy nhìn vào thành ngữ RAII, các công cụ khá tiện dụng và hữu ích.

0

Hãy xem những gì GCC 4.8 x86-64 Linux không

Chương trình:

#include <cstdio> 
int main() { 
    const char *s = "abc"; 
    char *sn = new char[4]; 
    sn[3] = '\0'; 
    std::printf("%s\n", s); 
    std::printf("%s\n", sn); 
} 

Compile và biên soạn lại:

g++ -ggdb -std=c++98 a.cpp 
objdump -CSr a.o 

Dữ liệu ra gồm:

const char *s = "abc"; 
8: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp) 
f: 00 
        c: R_X86_64_32S .rodata 
    char *sn = new char[4]; 
10: bf 04 00 00 00   mov $0x4,%edi 
15: e8 00 00 00 00   callq 1a <main+0x1a> 
         16: R_X86_64_PC32  operator new[](unsigned long)-0x4 
1a: 48 89 45 f8    mov %rax,-0x8(%rbp) 

Giải thích:

  • char *s = "abc" đi vào .rodata. Vì vậy, bạn không thể free nó theo bất kỳ cách nào.
  • char *sn = new char[4]; xuất phát từ đầu ra của operator new[]. Vì vậy, bạn nên giải phóng nó khi bạn có thể.
Các vấn đề liên quan