I am trying to transpose a 2D char array (in C) of unknown size rows and columns at run time. I use malloc to create the array and for loops to copy the chars form the original array to the new array. I am testing on a sample array of size 9x15 to create an array of 15x9 and the code works until my outer loop i =11 and then crash. In debug mode it shows Exception: Access violation writing to location 0xcdcdcdcd. The original array is read in from a file and is created using the same malloc code and works just fine. I have tried moving the code to main, but get the same exception. I am confused on how it does not create the array properly and would appreciate some input on how to correct the code or trouble shoot the issue better. My code is here
char **dest_grid = malloc(sizeof(char*) * source_col);
if (dest_grid == NULL) {
printf("Memory not assigned\n");
exit(EXIT_FAILURE);
}
else {
for (i = 0; i <= source_row; i++) {
dest_grid[i] = malloc(sizeof(char) * source_row);
}
for (i = 0; i < source_col; i++) {
for (j = 0; j < source_row; j++) {
if (j == source_row) {
dest_grid[i][j] = '\0';
}
else {
dest_grid[i][j] = source_grid[j][i];
}
}
}
}
for (i = 0; i < source_col; i++) {
free(dest_grid[i]);
}
free(dest_grid);
edit: The size of the array is provided from the file when read into memory. Multiple arrays are read in from the file of various sizes.
After char **dest_grid = malloc(sizeof(char*) * src_c); allocates space for src_c pointers, the loop beginning for (i = 0; i <= src_r; i++) attempts to fill it in with src_r+1 pointers, which is wrong.
if (dest_grid == NULL) tests for memory allocation failure, but this is after dest_grid was already used, in assigning values to dest_grid[i].
There is no code to test whether the memory allocations for dest_grid[i] fail.
dest_grid[i][j] = NULL; should be dest_grid[i][j] = '\0';, because NULL represents a null pointer, not a null character, and some definitions of it may cause compiler errors in this use.
free(dest_grid); releases the memory allocated to dest_grid, but the individual allocations to dest_grid[i] have not been freed.
Related
I'm taking input from a user to continue with my program. Everything runs perfectly fine until I attempt to input a string into the 2D array, cityName. As soon as I input the string the program crashes.
//dynamically allocate memory for user input (integers)
int *xOfCity = calloc(numOfCities, sizeof(int));
int *yOfCity = calloc(numOfCities, sizeof(int));
//dynamically allocate memory for user input (city names)
char **cityName = (char **) calloc(numOfCities, sizeof(char *));
for (int i = 0; i < numOfCities; i++)
cityName[i] = (char *) calloc(CITY_NAME + 1, sizeof(char));
int dxOfFront, dyOfFront;
//read in data from user
for (int i = 0; i < numOfCities; i++) {
scanf("%d", &xOfCity[i]);
if (xOfCity[i] > MAX_GRAPH || xOfCity[i] < MIN_GRAPH)
return ERROR;
scanf("%d", &yOfCity[i]);
if (yOfCity[i] > MAX_GRAPH || yOfCity[i] < MIN_GRAPH)
return ERROR;
for (int j = 0; j < CITY_NAME; j++)
scanf("%s", cityName[i][j]);
}
To be sure that the 2D array was the problem I commented it out and ran the program only taking the integers as inputs, and the program ran fine. I tried allocating the array in a different way, but that didn't seem to work either.
Why would my program crash upon entering a string?
It's important here to keep track of your pointer dereferences.
You start with a char**, and you access it after dereferencing it twice - that is, the two indexes, i and j. When you access cityName[i][j], you're not referencing the char*, you're actually passing the value of the first character itself. That means your program is using a character as a pointer!
You'd be better simply doing:
scanf("%s",cityName[i]);
The j is not necessary.
I am working on a project that I have made use of Calloc and I am trying to free the memory at the end of my main{} function. However, after the program finishes running and I click on the stop, I get this "proj.exe has triggered a breakpoint."
at this set of codes:
while (freeSpace != NULL) {
free(freeSpace++);
}
Here are my codes for allocating memory:
scanf("%d", &SEG);
BLOCKS = 128 / SEG;
for (int k = 0; k < BLOCKS; k++)
{
memory = (int *)calloc(BLOCKS, sizeof(int));
// handle memory allocation failure
}
for (int i = 0; i < BLOCKS; i++)
{
memory[i] = (int *)calloc(SEG, sizeof(int));
// handle memory allocation failure
}
for (int l = 0; l < BLOCKS+5; l++)
{
//freeSpace = (int*)malloc(l * sizeof(int));
freeSpace = (int *)calloc( BLOCKS + 5, sizeof(int));
// handle memory allocation failure
}
for (int o = 0; o < BLOCKS; o++)
{
memorySpace = (int *)calloc(BLOCKS, sizeof(int));
// handle memory allocation failure
}
`
This is the part where I free my memory:
while (freeSpace != NULL) {
free(freeSpace++);
}
Can someone please assist me?
Its really hard to fix your issue because it seems like that these are only a part of your code or it is a prototype?
The following code only based on some 'guess':
int main()
{
scanf("%d", &SEG);
BLOCKS = 128 / SEG;
int* memory = (int *)calloc(BLOCKS+1, sizeof(int*)); // the last is a 'NULL' pointer
memset(memory, 0, sizeof(int*)*BLOCKS+1);
for (int i = 0; i < BLOCKS; i++)
{
memory[i] = (int *)calloc(SEG, sizeof(int));
// handle memory allocation failure
}
while (memory != NULL) {
free(memory++);
}
}
I think you are misunderstanding how pointers work when allocating arrays. Your very first loop has a memory leak in it because you are changing what I am assuming the "memory" pointer is pointing to.
To allocate an array in C would be like below.
int *bigspace;
bigspace = malloc(20 * sizeof(int));
Here we made the pointer "bigspace" point to a new chunk of memory 20 times the size of an integer which is an array. If you did something like below..
int *bigspace;
bigspace = malloc(20 * sizeof(int));
bigspace = malloc(20 * sizeof(int));
This would be no bueno. We are first making "bigspace" pointer point to a chunk of memory (array of ints) and then we are changing what "bigspace" is pointing to by making it point to a new chunk of memory. This means your first chunk of memory does not have a pointer to it anymore and that memory is leaked!
I think the problem is that the value of freeSpace++ is garbage at the end of your allocated memory.
Free a garbage pointer causes the problem.
Whats wrong with this function, which is expected to add a row and a column to given 2D array? Matrix is symmetric.
void updateMatrix(double ***mat, int size, double *vec)
{ // mat is sizeXsize matrix, length of vec is size+1
*mat = (double**)realloc(*mat, (size + 1)*sizeof(double*));
(*mat)[size] = (double*)malloc((size + 1)*sizeof(double));
for(int i = 0; i < size + 1; i++) {
(*mat)[size][i] = vec[i];
}
for(int i = 0; i < size; i++) {
(*mat)[i] = (double*)realloc((*mat)[i], (size + 1)*sizeof(double));
(*mat)[i][size] = vec[i];
}
}
Your realloc is returning NULL in the second for loop..
I'm trying to figure out why.
Have you allocated everything before hand? Because chances are you might be passing a non NULL and non malloced pointer to realloc. And that is forbidden/will cause errors
Or, as says #MichaelDorgan , you could just be passing a gigantic size to your function but i sincereley hope you are not trying to allocate a few Go for an array. Otherwise i'm curious as to its use.
I have a very simple snippet below for which I am trying to figure out the reason for getting a segmentation fault.
int main (int argc, char** argv)
{
const int size = 2;
char** test1 = NULL;
int index = 0;
test1=(char**)malloc(sizeof(char*) * size);
if (test1 != NULL)
{
for (index = 0; index < size ; index++)
{
test1[index]=(char*)malloc(sizeof(char));
test1[index]='a';
}
//Removing this block does not result in seg fault - start
for (index = 0 ; index < size ; index++)
{
free(test1[index]); //Seg. fault here
}
//Removing this block does not result in seg fault - end
free(test1);
}
return 0;
}
If I remove the block enclosed within start and end comment - I do not see seg fault. But I think that would result in a leak.
Any help is much appreciated.
I think you meant to dereference the test1[index]. Your code overwrites the address of the allocated memory with 'a', hence when it tries to free the memory it segs fault because 'a' is not a valid address.
test1[index]=(char*)malloc(sizeof(char));
*test1[index]='a';
This works as well
test1[index][0]='a';
You start out fine:
test1=(char**)malloc(sizeof(char*) * size);
if (test1 != NULL) {
Your loop is not:
for (index = 0; index < size ; index++) {
test1[index]=(char*)malloc(sizeof(char));
test1[index]='a';
}
First, you allocating only one byte for what is supposed to be a row of characters (since you have only one "size" variable, I assume you want your 2d array to be square: 2x2. So you need to multiply by size here like you did in the outer loop. You don't need "sizeof(char)", that's just a long-winded way of typing "1".
But worse than that, after allocating the row too short, you then throw that memory away by overwriting the pointer with a character (you should have gotten a compiler warning here). That's disaster waiting to happen and a memory leak.
What you really mean is:
for (index = 0; index < size ; index++) {
test1[index]=malloc(size);
test1[index][0]='a';
}
Here is basically a simple code of double pointer and what I am trying to use:
int argsCount = 1;
char **cmdArgs1 = malloc((argsCount + 1)*sizeof(char*));
I want to input values into the cmdArgs1 and here is basically what I am doing and causing seg fault
for(counter = 0; counter < argsCount; counter++)
{
strcpy(cmdArgs1[counter],"ls");
}
I'm thinking that I can't use "cmdArg1[counter]" to copy to "ls" because the double pointer doesn't work that way? I'm not sure...
Even I think it's a bit vague, but I don't know how to phrase the question well, I will try to update based on the comment. Thx!
Your cmdArgs1 is a pointer to a pointer, meaning that it is not enough to allocate space for the array itself. You need to allocate space for the individual arrays of characters (or for the individual C string).
You can do it in a separate call of malloc
for(counter = 0; counter < argsCount; counter++)
{
cmdArgs1[counter] = malloc(strlen("ls")+1); // +1 for null terminator
strcpy(cmdArgs1[counter], "ls");
}
or with strdup:
for(counter = 0; counter < argsCount; counter++)
{
cmdArgs1[counter] = strdup("ls");
}
In both cases your program is liable for freeing the elements of the array before freeing the array itself:
for(counter = 0; counter < argsCount; counter++)
{
free(cmdArgs1[counter]);
}
free(cmdArgs1);