我是C ++的新手,我有很多Objective-C经验。
我正在尝试将一个c字符串数组(即char **
)作为我的类中的实例变量,它在我的构造函数中被分配和填充,然后在另一个我想要的成员函数中打印出整个“网格”。
分配工作,我用字符串填充我的数组(现在只是“aaaaaaa”等等)。检查我的构造函数的结尾,我看到每一行都已成功创建并按预期填充。
然而,我然后调用我的printGrid()函数,然后事情变得奇怪。如果我要打印25行,比如说,前12个左右会打印出垃圾,剩下的13个按预期打印出来。所以我似乎在某处践踏记忆,我不确定在哪里。
我的代码可能看起来有点乱,因为我一直在尝试不同的东西,所以我会尽量让它看起来尽可能具有凝聚力。
main.cpp:我在哪里调用函数
#include <iostream>
#include "Bitmap.h"
using namespace std;
int main (int argc, char * const argv[]) {
Bitmap bitmap(15, 25);
bitmap.printBitmap();
return 0;
}
Bitmap.h:我班级的标题
class Bitmap {
private:
char **_bitmap;
void printLine(char const*lineString);
int _width;
int _height;
public:
Bitmap();
Bitmap(int width, int height);
void printBitmap();
};
Bitmap.cpp:行动发生的地方
#include <iostream>
#include "Bitmap.h"
using namespace std;
Bitmap::Bitmap() {
// allocate space for the bitmap
int numRows = 20;
int numColumns = 30;
Bitmap(numRows, numColumns); // Can I even safely do this? I'm not using the default constructor in my main() but I'm still curious.
}
Bitmap::Bitmap(int width, int height) {
_width = width;
_height = height;
_bitmap = (char **)malloc(sizeof(char*) * height); // FIXED this line (used to be char, now it's char *).
for (int currentRow = 0; currentRow < height; currentRow++) {
_bitmap[currentRow] = (char *)malloc((sizeof(char) * width));
snprintf(_bitmap[currentRow], width, "%s", "1");
for (int currentColumn = 0; currentColumn < width; currentColumn++) {
_bitmap[currentRow] = strcat(_bitmap[currentRow], "a");
}
printf("currentRow %0d: %s\n",currentRow, _bitmap[currentRow]); // Each row prints out FINE here, as expected
}
}
void Bitmap::printBitmap() {
int numColumns =_width;
int numRows = _height;
if (NULL == _bitmap)
return;
// iterate over the bitmap, line by line and print it out
for (int currentRow = 0; currentRow < numRows; currentRow++) {
// If there are, say, 25 lines, the first 12 or so will be garbage, then the remaining will print as expected
printLine((char const *)_bitmap[currentRow]);
}
}
void Bitmap::printLine(char const*lineString) {
printf(":%s\n", lineString);
}
这是针对学校的,教授不允许使用C ++向量或字符串。否则,是的我知道我应该使用那些。感谢您的所有建议。
答案 0 :(得分:6)
红旗:
_bitmap = (char **)malloc(sizeof(char) * height);
应该是
_bitmap = (char **)malloc(sizeof(char*) * height);
您需要指向char*
的指针,而不是指向char
的指针。
答案 1 :(得分:5)
_bitmap = (char **)malloc(sizeof(char) * height);
应该是
_bitmap = (char **)malloc(sizeof(char*) * height);
并且只有在您编码C时才会这样做。
如果您绝对需要位图是连续的,那么最好使用new / delete,
Vector< Vector < char > >
如果你不这样做。
另外,strcat似乎是一个奇怪的选择,因为你还没有初始化内存。即不一定是0,所以字符串没有结束。这可能会导致你的记忆踩踏。尝试使用strcpy(如果你想要安全,请使用strncpy)。
答案 2 :(得分:4)
与默认构造函数中的此注释相关:
Bitmap(numRows, numColumns); // Can I even safely do this? I'm not using
// the default constructor in my main() but
// I'm still curious.
这不符合你的想法。这是不调用其他构造函数进行额外的初始化。相反,这会使用Bitmap
和numRows
创建另一个临时未命名的numColumns
对象,然后立即调用其析构函数。此语句的作用类似于没有名称的局部变量。
在您的情况下,您可以通过给出一个构造函数默认参数来提供默认构造函数:
public:
Bitmap(int width = 20, int height = 30);
答案 3 :(得分:4)
这个malloc没有为字符串末尾的0字节留出空间:
_bitmap[currentRow] = (char *)malloc((sizeof(char) * width));
由于“sizeof(char)”的定义是1,你可以这样做:
_bitmap[currentRow] = (char *)malloc(width+1);
在这个结构中:
for (int currentColumn = 0; currentColumn < width; currentColumn++) {
_bitmap[currentRow] = strcat(_bitmap[currentRow], "a");
}
你真的不想使用strcat
,只需直接分配字符:
for (int currentColumn = 0; currentColumn < width; currentColumn++) {
_bitmap[currentRow][currentColumn] = 'a';
}
_bitmap[currentRow][width] = 0; // and don't forget to terminate the string
答案 4 :(得分:1)
除了所有其他答案:
Bitmap::Bitmap() {
// allocate space for the bitmap
int numRows = 20;
int numColumns = 30;
Bitmap(numRows, numColumns); // Can I even safely do this? I'm not using the default constructor in my main() but I'm still curious.
}
不,你不能这样做。每个构造函数都是独立的,它们不能相互委派。
对于内存管理,请使用专用资源管理类,它们将自动为您控制内存。该标准提供了一系列优秀的课程,std::vector<std::string>
将在这种情况下很好地服务于此目的。
答案 5 :(得分:0)
以下 应正确分配(尚未测试)。
_bitmap = new char*[height];
for (int currentRow = 0; currentRow < height; currentRow++)
{
_bitmap[currentRow] = new char[width];
snprintf(_bitmap[currentRow], width, "%s", "1");
for (int currentColumn = 0; currentColumn < width; currentColumn++)
{
_bitmap[currentRow] = strcat(_bitmap[currentRow], "a");
} // Each row prints out FINE here, as expected
printf("currentRow %0d: %s\n",currentRow, _bitmap[currentRow]);
}
还要确保定义复制构造函数,析构函数和赋值运算符,以确保内存不会泄漏并删除数组。
答案 6 :(得分:0)
这里我认为你想要malloc
中的sizeof(char *)_bitmap = (char **)malloc(sizeof(char) * height);
另外,当你用“a”填充字符串时,你必须确保你没有覆盖任何内存:你分配了宽度字符,你打印“1”,然后连接“a”宽度时间,将超过分配的内存1(更不用说没有留下任何空间终止
答案 7 :(得分:0)
你的malloc()
电话对我来说不合适,但也许我错过了一些东西。
我应该看到的是malloc()
对数组存储的调用。如果你想要10个C字符串,那就是malloc(10 * sizeof (char *))
。然后我应该看到更多的malloc()
调用实际分配10个字符串本身使用的内存。
但我只看到一个malloc()调用,似乎认为它是分配字符串数组内存,而不是字符串指针数组内存。