Reputation: 25
I have a 2d array of words.
void main() {
const int rowsCount = 2;
const int colsCount = 5;
char*** szData = new char** [rowsCount];
//Allocate memory for each row
for (int i = 0; i < rowsCount; i++)
{
szData[i] = new char* [colsCount]; //how many words in every row
for (int j = 0; j < colsCount; j++)
{
szData[i][j] = new char[15]; //maximum symbols in a word
}
}
//Assign some data
for (int i = 0; i < rowsCount; i++)
{
char s[] = "Williams";
szData[i][0] = s;
sprintf(szData[i][0], "Williams%d", 0);
sprintf(szData[i][1], "J.%d", 0);
sprintf(szData[i][2], "#3%d", 0);
sprintf(szData[i][3], "100%d", 0);
sprintf(szData[i][4], "01.13%d", 0);
}
...
}
While assigning data, I tried to change this
sprintf(szData[i][0], "Williams%d");
to this
char s[] = "Williams";
szData[i][0] = s;
Why do I keep getting the message that my project "has trigerred a breakpoint"?
Is there any alternative to sprintf
using array of characters? Cannot use string
(one of the condition of this task)
Also, not so necessary, but if I delete 0 at the end here
sprintf(szData[i][0], "Williams%d", 0);
sprintf(szData[i][1], "J.%d", 0);
sprintf(szData[i][2], "#3%d", 0);
sprintf(szData[i][3], "100%d", 0);
sprintf(szData[i][4], "01.13%d", 0);
there will appear some numbers after every word. For example: Williams3937516
. Why is that?
Full code:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <conio.h>
using namespace std;
void main() {
const int rowsCount = 2;
const int colsCount = 5;
char*** szData = new char** [rowsCount];
//Allocate memory for each row
for (int i = 0; i < rowsCount; i++)
{
szData[i] = new char* [colsCount]; //how many words in every row
for (int j = 0; j < colsCount; j++)
{
szData[i][j] = new char[15]; //maximum symbols in a word
}
}
//Assign some data
for (int i = 0; i < rowsCount; i++)
{
char s[] = "Williams";
szData[i][0] = s;
sprintf(szData[i][0], "Williams%d");
sprintf(szData[i][1], "J.%d", 0);
sprintf(szData[i][2], "#3%d", 0);
sprintf(szData[i][3], "100%d", 0);
sprintf(szData[i][4], "01.13%d", 0);
}
//print all the elements
for (int i = 0; i < rowsCount; i++)
{
for (int j = 0; j < colsCount; j++)
{
cout << szData[i][j] << " ";
}
cout << endl;
}
//free memory here
for (int i = 0; i < rowsCount; i++)
{
for (int j = 0; j < colsCount; j++)
{
delete[] szData[i][j];
}
}
for (int i = 0; i < rowsCount; i++)
{
delete[] szData[i];
}
delete[] szData;
}
Upvotes: 1
Views: 222
Reputation: 1551
If you trace back the assignment of this pointer:
char s[] = "Williams";
You'll find you are attempting to free its memory here:
delete[] szData[i][j];
However, you can't do that -- the string "Williams"
was never allocated with new
, so it can't be freed with delete
. In fact, it's statically allocated, in your binary. So the heap complains, and that's the cause of the breakpoint.
If you're going to delete
everything in szData
, you need to make sure it's all allocated on the heap with new
.
Second problem - when you call:
sprintf(szData[i][0], "Williams%d", 0);
You're overwriting the bounds of the memory you supplied. Remember, your buffer only has "Williams"
number of bytes (plus one)! You don't have space to tack an integer's string representation on the end of that. Use sprintf_s
and make sure your buffers have enough room!
Third problem - writing to statically allocated string data is enormously sketchy and may not work in all cases.
Bottom line: dynamic allocate a buffer of the right size for everything, and your code will work.
Here's a simple example to fix that section of code. It demonstrates the concepts that fix your code, but it's not really appropriate for your codebase as-is, you'll need to work it in properly.
const size_t MAX_NAME_LENGTH = 15; // Fix this magic number to be whatever max name length you want
char *s = new char[MAX_NAME_LENGTH]; // allocate on heap
strcpy_s(s, MAX_NAME_LENGTH, "Williams"); // use strcpy_s for safety
szData[i][0] = s;
sprintf_s(szData[i][0], MAX_NAME_LENGTH, "Williams%d", 0); // use sprintf_s for safety
Upvotes: 1