2011-10-12 42 views
7

Nói rằng tôi có một mảng động như:C++ Xóa một phần của mảng động

int* integers = new int[100]; 

Có cách nào để xóa chỉ là một phần của mảng như:

int* integers2 = integers + 50; 
delete[] integers2; 

Tôi muốn không chỉ xóa mọi thứ 50 và hơn thế nữa, nhưng nếu tôi gọi một lệnh xóa khác [] trên mảng số nguyên ban đầu, thì nó sẽ chỉ xóa số lượng bộ nhớ chính xác và không cố gắng xóa số lượng đã cấp ban đầu và lỗi seg.

Tại sao tôi muốn thực hiện điều này: Tôi có cấu trúc dữ liệu được cấu trúc theo cấp độ mảng và tôi muốn có thể tạo cấu trúc dữ liệu này từ một mảng đầy đủ. Vì vậy, tôi muốn có thể nói

int* level1 = integers; 
int* level2 = integers + 50; 
int* level3 = integers + 100; 

Nhưng khi cấp 3 không còn cần thiết, cấu trúc dữ liệu sẽ tự động xóa [] level3. Tôi cần phải biết rằng điều này sẽ hành xử một cách chính xác và không chỉ phá hủy mọi thứ trong mảng. Nếu nó sẽ sau đó tôi cần phải chỉ tạo mảng mới và sao chép nội dung trên, nhưng nó sẽ là tốt đẹp để tránh làm điều đó vì lý do hiệu suất.

Chỉnh sửa: Mọi người dường như đang nhảy đến kết luận rằng tôi chỉ nên sử dụng vùng chứa kích thước động (ví dụ: vector, deque) ở vị trí đầu tiên cho cấu trúc dữ liệu của tôi. Tôi đang sử dụng mức độ mảng cho một lý do chính đáng (và chúng không có kích thước bằng nhau như tôi làm cho nó trông giống như trong ví dụ của tôi). Tôi chỉ đang tìm kiếm một cách tốt để có một hàm tạo cho cấu trúc dữ liệu của tôi lấy một mảng hoặc một vectơ và không cần phải sao chép các nội dung ban đầu vào trong cấu trúc dữ liệu mới.

+0

std :: deque là những gì bạn đang tìm kiếm. –

+0

Không, không. Trong thực tế những gì tôi đang tìm kiếm về cơ bản là một cách để tạo ra một deque từ một mảng mà không cần sao chép các giá trị hơn từ mảng ban đầu. – Floss

+0

'std :: deque' hoạt động giống như một mảng tự động định kích thước. Một mảng thẳng lên không thể được thay đổi kích thước (trừ khi nó được phân bổ với 'malloc', và sau đó chỉ kích thước lên) –

Trả lời

9

Không, điều này sẽ không hoạt động chính xác. Bạn chỉ có thể delete[] con trỏ mà bạn nhận được từ new[], nếu không kết quả là không xác định và những điều xấu có thể xảy ra.

Nếu bạn thực sự cần mảng để nhỏ hơn, bạn phải cấp phát một mảng mới và sao chép nội dung theo cách thủ công.

+0

Cảm ơn bạn đã thông tin – Floss

0

Thông thường khi bộ nhớ được cấp phát, có một số công cụ dọn dẹp trước con trỏ.

tức là dữ liệu houskeeping (con trỏ)

Bạn sẽ làm hỏng điều đó.

0
int* integers2 = integers + 50; 
delete[] integers2; 

Sẽ không làm việc vì mới được tạo ra trên int *, vì vậy không gian của 100 int đã được giao cho các số nguyên, bây giờ integers2 chỉ là một con trỏ đến vị trí thứ 50 của số nguyên, nó không có không gian được gán cho nó của nó riêng, do đó, việc sử dụng xóa sẽ không xóa phần còn lại của số nguyên 2, nó sẽ chỉ cho kết quả thất thường.

Những gì bạn có thể làm là sao chép 50 đầu tiên trong mảng khác và xóa hoàn toàn mảng trước đó.

xóa sẽ chỉ xóa con trỏ có khoảng trống được gán cho nó, sử dụng xóa tới con trỏ khác trỏ đến khoảng trống được gán cho con trỏ đầu tiên sẽ không xóa bất kỳ dấu cách nào được gán cho con trỏ đầu tiên.

xóa [] số nguyên 2 sẽ không xóa bất kỳ dấu cách nào được gán cho số nguyên1 hoặc bất kỳ con trỏ nào khác.

0

Trình phân bổ động (như new) thường không thích bạn giải phóng phần bộ nhớ họ đã cung cấp cho bạn.Nếu bạn sử dụng <malloc.h> các chức năng thư viện được xác định malloc()free() thay vì newdelete, thì bạn có thể sử dụng realloc(), mặc dù trong hầu hết các trường hợp, bạn sẽ quan tâm đến sự khác biệt về kích thước mà nó sẽ sao chép cho bạn.

Quy tắc kích thước động thường sử dụng quy tắc mũ để thay đổi kích thước: nếu bạn hết dung lượng, chúng (ví dụ) tăng gấp đôi phân bổ (và sao chép dữ liệu cũ), nếu bạn xóa dữ liệu cho đến khi bạn đang sử dụng (ví dụ) ít hơn một nửa phân bổ mà họ sao chép vào một phân bổ nhỏ hơn. Điều này có nghĩa là bạn không bao giờ lãng phí hơn một nửa bộ nhớ và chi phí sao chép cho mỗi phần tử được thêm vào hoặc bị xóa có hiệu quả không đổi. Thực hiện tất cả điều này là một nỗi đau trong ass, mặc dù, vì vậy chỉ cần sử dụng std::vector và để cho nó làm điều đó cho bạn :).

+0

Sử dụng std :: vector không giải quyết được sự cố ban đầu của tôi. Tôi đã sử dụng một tập hợp các mảng tầng thay vì một mảng thay đổi kích thước động (ví dụ: vector) vì một lý do. Vấn đề không phải là cách nó được lưu trữ, nhưng tôi đang cố gắng tạo một véc tơ hoặc mảng động là một đầu vào cho cấu trúc dữ liệu của tôi mà không cần sao chép toàn bộ nội dung từ cấu trúc dữ liệu gốc – Floss

+0

@ Floss: 'Tập hợp các mảng' là gì? Mảng mảng? Và có gì sai với 'vector :: data()'? –

0

Không, bạn không thể làm điều này với một mảng có kích thước cố định được phân bổ với new[]. Nếu bạn muốn có mảng động, hãy sử dụng một trong các vùng chứa STL, chẳng hạn như std::vector.

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