2010-04-29 32 views
7

Tôi đã tạo cấu trúc để giữ một số dữ liệu và sau đó khai báo một vectơ để giữ cấu trúc đó.segfault trên vector <struct>

Nhưng khi tôi thực hiện push_back, tôi nhận được sự phân đoạn chết tiệt và tôi không biết tại sao!

struct của tôi là định nghĩa như sau:

typedef struct Group 
{ 
    int codigo; 
    string name; 
    int deleted; 
    int printers; 
    int subpage; 

    /*included this when it started segfaulting*/ 
    Group(){ name.reserve(MAX_PRODUCT_LONG_NAME); } 
    ~Group(){ name.clear(); } 
    Group(const Group &b) 
    { 
    codigo = b.codigo; 
    name = b.name; 
    deleted = b.deleted; 
    printers = b.printers; 
    subpage = b.subpage; 
    } 
    /*end of new stuff*/ 
}; 

Ban đầu, struct không có sao chép, nhà xây dựng hoặc destructor. Tôi đã thêm chúng sau khi tôi đọc bài đăng này bên dưới.

Seg fault after is item pushed onto STL container

nhưng kết quả cuối cùng giống nhau.

Có một điều khiến tôi phiền lòng! Khi tôi lần đầu tiên đẩy một số dữ liệu vào vectơ, mọi thứ đều ổn. Sau này trong mã khi tôi cố gắng đẩy thêm một số dữ liệu vào vectơ, ứng dụng của tôi chỉ là segfaults!

Các vector được khai báo

vector<Group> Groups 

và là một biến toàn cầu đến file mà tôi đang sử dụng nó. Không externs bất cứ nơi nào khác, vv ...

tôi có thể theo dõi các lỗi:

_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage- this->_M_impl._M_start); 

trong vector.tcc khi tôi xong việc thêm/sao chép các yếu tố cuối cùng để các vector ....

Theo như tôi có thể nói. Tôi không nên cần bất cứ điều gì để làm với một nhà xây dựng bản sao như là một bản sao nông nên là đủ cho việc này. Tôi thậm chí không phân bổ bất kỳ không gian nào (nhưng tôi đã dự trữ chuỗi để thử).

Tôi không biết vấn đề là gì!

Tôi đang chạy mã này trên OpenSuse 10.2 với gcc 4.1.2

Tôi không thực sự để mong muốn nâng cấp gcc vì các vấn đề tương thích ngược ...

Mã này làm việc "một cách hoàn hảo" trên máy tính của tôi. Tôi biên soạn nó với gcc 3.4.5 mingw mà không có bất kỳ vấn đề nào ...

trợ giúp!

--- ... ---

::: EDIT :::

Tôi đẩy dữ liệu

Group tmp_grp; 

(...) 

tmp_grp.name = "Nova "; 
tmp_grp.codigo=GetGroupnextcode(); 
tmp_grp.deleted=0; 
tmp_grp.printers=0; 
tmp_grp.subpage=0; 
Groups.push_back(tmp_grp); 
+1

Các mã đẩy nó vui lòng. –

+1

struct struct của bạn không cần constructor sao chép, và nó là một ý tưởng tồi để cung cấp nó - constructor sao chép mặc định làm mọi thứ bạn cần. Bạn cũng không cần typedef trên struct.Nó cũng không cần destructor, và có lẽ không phải là constructor có kích thước. –

+0

@Neil. Tôi biết! Tôi đã thêm chúng vào "tuyệt vọng" –

Trả lời

0

Vâng ...

valgrind để giải cứu! Những gì được gọi cho tôi trong nhật ký valgrind là phần này.

Invalid write of size 4 
==4639== at 0x805BDC0: ChangeGroups() (articles.cpp:405) 
==4639== by 0x80AC008: GeneralConfigChange() (config.cpp:4474) 
==4639== by 0x80EE28C: teste() (main.cpp:2259) 
==4639== by 0x80EEBB3: main (main.cpp:2516) 

Tại thời điểm này trong file tôi đã làm điều này

Groups[oldselected].subpage=SL.selected_code(); 

và những gì nếu oldselected là bên ngoài bờ cõi của các véc tơ?

Trong trường hợp này những gì đã xảy ra là oldselected có thể là -1 ... và mặc dù điều này không được đâm vào thời điểm này, nó đang viết một cái gì đó ở một nơi khác ...

tôi có lẽ nên bắt đầu sử dụng at() và kiểm tra ngoại lệ hoặc chỉ kiểm tra xem "oldselected" là> 0 và < Groups.size() [giải pháp ưu tiên].

Vì vậy, hãy kudo với John và Josh vì đã nhắc tôi về valgrind.

Tôi đã sử dụng nó trước đây, nhưng không bao giờ cần thiết để làm bất cứ điều gì đáng kể với nó (may mắn thay: D).

Điều thú vị là trong các cửa sổ, tôi không nhận được phân đoạn này. Vấn đề là như vậy ... Tôi đoán rằng nó có cái gì đó để làm với quản lý bộ nhớ và trình biên dịch ... nó thực sự eludes tôi.

Cảm ơn tất cả mọi người cho đầu vào;)

Cheers

1

Bạn chắc chắn nên loại bỏ các destructor. C++ sẽ tự động gọi destructor của tất cả các thành viên dữ liệu, và làm những việc cho các thành viên đã có một destructor như thế là không cần thiết và có thể không an toàn.

Nhưng, tôi không thấy bất kỳ điều gì sai với mã của bạn. Bạn sẽ phải đăng thêm một chút nữa. Hãy thử mở rộng phần (...) - hiển thị cho chúng tôi tất cả mã liên quan đến vectơ.

6

Giống như Neil nói, bạn không cần một constructor mặc định, copy constructor, hoặc destructor:

  • std::string dọn dẹp sau khi bản thân, vì vậy destructor của bạn là không bao giờ cần thiết.
  • Trình tạo bản sao nông được cung cấp bởi trình biên dịch sẽ hoạt động tốt.
  • std::string::reserve là không cần thiết, vì std::string sẽ tự động cấp phát bộ nhớ khi cần, nhưng có thể mang lại lợi ích hiệu suất.

Mã mà bạn đã đăng có vẻ chính xác (và trông rất đơn giản và dễ hiểu, vì vậy thật khó để biết một lỗi có thể xuất hiện ở đâu). Vì vậy, tôi nghi ngờ rằng bạn đang làm hỏng bộ nhớ ở nơi khác trong mã của bạn và rằng vector<Group> chỉ đơn giản là nạn nhân.

Thử cài đặt Valgrind (OpenSuse nên cung cấp gói) và chạy ứng dụng của bạn thông qua nó (từ dòng lệnh, chỉ cần chạy valgrind my-app) để xem Valgrind có thể bắt bất kỳ hỏng bộ nhớ nào không.

1

Lỗi bộ nhớ như thế này có thể được gây ra bằng cách xóa cùng một bộ nhớ hai lần hoặc xóa bộ nhớ bạn không nhận được từ mới. Các lỗi thường xảy ra lâu sau khi thực tế ở những nơi như thế này. Như DeadMG đã tuyên bố cài đặt valgrind và tìm kiếm các vấn đề bộ nhớ dường như không liên quan khác.

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