2014-01-24 34 views
1

我正在嘗試Scott Meyers Effective C++的一些代碼,特別是第3項。指向引用的分段錯誤指針

在他的著作中的代碼應該是非常相似,這(他離開了構造函數)

#include <iostream> 


class TextBlock { 
public: 
    TextBlock(char* ptr) : ptrText(ptr) 
    {} 
    char& operator[](std::size_t pos) const { 
     return ptrText[pos]; 
    } 
private : 
    char* ptrText; 
}; 

int main(int argc, char* argv[]) { 
    const TextBlock block("Hello"); 
    std::cout << block[0] << std::endl; 
    char* ptr = &block[0]; 
    *ptr = 'J'; 
    std::cout << block[0]; 
} 

在那裏我改變指針PTR內容的點(* PTR =「J」;) ,我得到了分段錯誤(通常在解引用未初始化或釋放的指針時發生)。這裏沒有發生,*ptr = 'J'出了什麼問題;

+0

指向引用的指針是不可能的。 – chris

+0

@MikeSeymour,就像標題一樣無關;) – chris

+0

@chris:對不起,我沒有注意到標題。 –

回答

4

TextBlock不擁有任何存儲。它指向內存中的一個常量字符串"Hello",並且您試圖修改只讀內容。

如果宣佈與自己的存儲局部變量,這會工作,如:

char test[32] ; 
strcpy(test, "Hello") ; 
const TextBlock block(test) ; 
char * ptr= &block[0] ; 

*ptr= 'J' ; 
0
#include <iostream> 


class TextBlock { 
public: 
    TextBlock(char* ptr) : ptrText(ptr) 
    {} 
    char& operator[](std::size_t pos) const { 
     return ptrText[pos]; 
    } 
private : 
    char* ptrText; 
}; 

int main(int argc, char* argv[]) { 
    char text[] = "Hello"; 
    const TextBlock block(text); 
    std::cout << block[0] << std::endl; 
    char* ptr = &block[0]; 
    *ptr = 'J'; 
    std::cout << block[0]; 
} 
0

是的這是真的! ptrText只記錄「hello」的ptr,「hello」是你不能改變的常量靜態文本。它沒有存儲任何東西〜所以你不能改變它。

1

你應該管理

ptrText

構件不是指向其中寫入是被禁止的一個恆定存儲區的指針,但作爲到基於堆棧基或參考可以完全控制的對象。

可以使用字符數組代替

#include <iostream> 

#define MAX_LENGTH = 1024 

class TextBlock { 
public: 
TextBlock(char* ptr) 
{ 
    memset(ptrText, 0, MAX_LENGTH); 
    memcpy(ptrText, ptr, strlen(ptr) < MAX_LENGTH?strlen(ptr):MAX_LENGTH); 
} 

char& operator[](std::size_t pos) const { 
    return ptrText[pos]; 
} 
private : 
char ptrText[MAX_LENGTH]; 

};