2014-09-19 57 views
1

在我的课堂我有:访问动态二维字符数组C++

private: 
    //... 
    char** mNumber; 
//... 

然后我初始化它的构造函数:

PhoneBook::PhoneBook() 
{ 
    mNumber = NULL; 

} 

我也有方法设置默认:

bool PhoneBook::setDefault() 
{ 
    lock(); 
    //... 

    for (uint8 i = 0; i < 5; ++i) 
    { 
     mNumber[i] = new char[5]; 
     for (uint8 k = 0; k < 4; ++k) 
     { 
      mNumber[i][k] = '0' + k; 
     } 
     mNumber[i][4] = '\0'; 
    } 
    unlock(); 
    return true; 
} 

在我的程序中,当我想写数字(我最多可以写五个数字)时,程序应该使用方法:

bool PhoneBook::write(DataOutputStream& s) 

{ 
    lock(); 
    //... 
    unsigned long checksum = 0; 

    for (uint8 j = 0; j <5; j++) 
    { 
     unsigned short k = 0; 
     do 
     { 
     char number= mUserNo[j][k]; 
     checksum += 0x000000FF & (number>> 8); //checksum is not problem here I guess 
     checksum += 0x000000FF & (number); 
     s.write_int8(userNo); 
     } while(mNumber[j][k++]=='\0'); 
    } 

    s.write_uint32(checksum); 
    s.flush(); 
    unlock(); 
    return (s.ok()); 
} 

它崩溃的行:

char userNo = mUserNo[j][k]; 

它也没有设置默认值(他们应该是他们没有在应用程序窗口中显示)。
Visual Studio 2010中提示:

Unhandled exception at 0x012b6fb8 (main_app.exe) in main_app: 0xC0000005: Access violation reading location 0xfdfdcdcd. 

我试图调试它,但无法找出什么是错的。我只能猜测这是2d数组的问题,因为我觉得他们不太好,当我尝试类似1D的东西时,它工作得很好。
请帮我看看代码,并让我们更好地理解C++中的multiD数组。
顺便说一句我不允许使用std :: string。只是不,我不能在这里使用它。

+0

嗯。你是不是打算在你的while循环条件中使用''=''来代替'!=',因为尽可能接近我在第一个元素上会看到的失败。其次,0xfdfdcdcd表示您正在访问边界页面的一部分,并且是已释放页面的一部分,这意味着您最好检查所有*您的索引逻辑。另外,你在'setDefault()'中设置'mNumber',但是在'write()'中使用'mUserNo'。他们是不同的名字。要么这是你的问题的一部分,要么你需要发布**真实**代码。 – WhozCraig 2014-09-19 07:43:27

+0

我真的建议使用'std :: vector'(或'char mNumber [5] [5]'如果你真的不被允许使用它)。 – Jarod42 2014-09-19 07:55:30

回答

0

如果你需要“char **”而不是std :: vector,你应该在填充默认值之前为它分配内存。像这样,

bool PhoneBook::setDefault() 
{ 
........ 
mNumber = new char*[5];   // allocating memory for mNumber 
for (uint8 i = 0; i < 5; ++i) 
{ 
    mNumber[i] = new char[4]; 
    for (uint8 k = 0; k < 4; ++k) 
    { 
     mNumber[i][k] = '0' + k; 
    } 
    mNumber[i][4] = '\0'; 
} 
unlock(); 
return true; 
} 
1

您只能将mNumber设置为NULL,因此通过mNumber(例如mNumber [j] [k])访问内存很可能会因访问冲突(1)而崩溃。您需要将mNumber初始化为一个有意义的值,在某处使用new!更妙的是,使用一个标准的集装箱像std::vector

// the declaration of mNumber, do not initialise mNumber to NULL! 
std::vector <char *> mNumber; // only need one * here! 

(1)这是发生在Windows和Linux中最常见的事,一些(但不是很多)操作系统/系统可能默默地让你这样做!