2010-09-01 26 views
5

Chương trình tôi đang làm việc trên các sự cố đôi khi cố gắng đọc dữ liệu tại địa chỉ 0xCCCCCCCC. Google (và StackOverflow) là bạn của tôi, tôi thấy rằng đó là mã gỡ lỗi MSVC cho biến ngăn xếp chưa được khởi tạo. Để hiểu được vấn đề có thể đến từ đâu, tôi đã cố gắng tái tạo hành vi này: vấn đề là tôi không thể làm được.Cách kết thúc bằng một con trỏ tới 0xCCCCCCCC

Câu hỏi là: bạn có đoạn mã cho biết cách con trỏ có thể kết thúc trỏ đến 0xCCCCCCCC không?

Cảm ơn.

+2

Bạn đã khởi tạo tất cả con trỏ của mình thành một giá trị đã biết chưa? –

+0

@ Trong silico +1, tôi không chắc câu hỏi ở đây là gì ... – synhershko

Trả lời

5

Biên dịch mã của bạn bằng /GZ compiler switch hoặc /RTCs switch. Đảm bảo rằng /Od switch cũng được sử dụng để vô hiệu hóa mọi tối ưu hóa.

s

phép stack frame kiểm tra lỗi run-time, như sau:

  • Khởi tạo các biến cục bộ đến một giá trị khác không. Điều này giúp xác định các lỗi không xuất hiện khi chạy trong chế độ gỡ lỗi. Có một cơ hội lớn hơn rằng các biến stack sẽ vẫn bằng không trong một bản xây dựng gỡ lỗi so với một bản phát hành do tối ưu hóa trình biên dịch của các biến stack trong một bản phát hành bản phát hành. Khi một chương trình đã sử dụng một vùng ngăn xếp của nó, nó sẽ không bao giờ được đặt lại về 0 bởi trình biên dịch. Do đó, các biến ngăn xếp tiếp theo, không khởi tạo xảy ra để sử dụng cùng một vùng ngăn xếp có thể trả về các giá trị còn lại từ việc sử dụng trước bộ nhớ ngăn xếp này.

  • Phát hiện quá tải và tràn ngập các biến cục bộ như mảng./RTCs sẽ không phát hiện overruns khi truy cập vào bộ nhớ mà kết quả từ trình biên dịch đệm trong một cấu trúc. Việc đệm có thể xảy ra bằng cách sử dụng align (C++),/Zp (Struct Alignment), hoặc gói, hoặc nếu bạn sắp xếp các phần tử cấu trúc theo cách yêu cầu trình biên dịch thêm phần đệm.

  • Xác minh con trỏ ngăn xếp, phát hiện tham nhũng con trỏ ngăn xếp. Stack pointer tham nhũng có thể được gây ra bởi một quy ước gọi không khớp. Ví dụ, bằng cách sử dụng một con trỏ hàm, bạn gọi một hàm trong một DLL được xuất dưới dạng __stdcall nhưng bạn khai báo con trỏ tới hàm là __cdecl.

9
int main() 
{ 
    int* p; 
} 

Nếu bạn xây dựng với Visual C++ debug runtime, đặt một breakpoint trong main(), và chạy, bạn sẽ thấy rằng p có giá trị 0xcccccccc.

+0

Đó là những gì tôi nghĩ, nhưng không, tôi chỉ có một số giá trị ngẫu nhiên chưa được khởi tạo. – gregseth

+0

Jim là chính xác. – EvilTeach

2

Tôi không có MSVC, nhưng mã này sẽ tạo ra sự cố và biên dịch mà không có cảnh báo.

Trong file f1.c:

void ignore(int **p) { } 

Trong file f2.c:

void ignore(int **p); 
int main(int c, char **v) 
{ 
    int *a; 
    ignore(&a); 
    return *a; 
} 

Các cuộc gọi đến ignore làm cho nó trông giống như a có thể được khởi tạo. Tôi nghi ngờ trình biên dịch sẽ cảnh báo trong trường hợp này, vì nguy cơ cảnh báo có thể là dương tính giả.

+1

Trong cả Visual C++ 2008 và 2010, mã chính xác này tạo ra cảnh báo mức 1 C4700: "biến cục bộ uninitialized 'a' được sử dụng". Bạn sẽ cần phải có 'ignore' lấy một con trỏ hoặc tham chiếu đến' int * 'để có bất kỳ cơ hội nào mà' a' được khởi tạo bởi lệnh gọi 'ignore'. –

+0

Bạn có thể giải thích về nguy cơ dương tính giả không? – Tomas

+0

Không có cảnh báo và không có 0xCC ... địa chỉ trên máy tính của tôi. Có tùy chọn biên dịch đặc biệt nào để bật tính năng này không? – gregseth

0

Làm thế nào về điều này? Bỏ qua cảnh báo mà VC ném trong khi chạy.

struct A{ 
    int *p; 
}; 

int main(){ 
    A a; 
    cout << (void *)a.p; 
} 
Các vấn đề liên quan