Segmentation fault while trying to make a Matrix in C [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
well, i'm working in C. I want to make a function that return a matrix[][].
This is my function:
char **mapa(int largo,int ancho)
{
char **matriz;
int i,j;
matriz = (char **)malloc(sizeof(char)*largo);
for(i = 0; i < largo; ++i)
{
matriz[i]= (char *)malloc(sizeof(char)*ancho);
}
for(i = 0; i < largo; i++)
{
for(j = 0; j < ancho; j++)
{
matriz[i][j] = 'k';
}
}
for(i = 0; i < largo; i++)
{
for (j = 0; j < ancho; j++)
{
printf("%c",matriz[i][j]);
}
}
return matriz;
}
Using gdb it give me this:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004008b8 in mapa (largo=10, ancho=10) at main.c:18
18 matriz[i][j] = 'k';
I don't know where the error is, if someone can give me a hand i'll be very gratefull.
Many thanks.

char **matriz;
int i,j;
matriz = (char **)malloc(sizeof(char)*largo);
Your matriz variable is a pointer to an array of pointers, each of which points to an array of char. You first need to allocate memory for the array of pointers, which requires largo times the size of the pointers, which is sizeof (char *). You only allocate space for largo times the size of a single char.
The easiest way to get the allocation right is to use the following pattern:
p = malloc (n * sizeof *p);
In other words, allocate n times the size of whatever p points to. This will automatically allocate the right amount regardless of the type of p, assuming you get the n right. If you're declaring the pointer in the same line, it looks a little different:
T *p = malloc (n * sizeof *p); /* For some type T */
In this case there is an asterisk before p on both sides. This difference is something you will have to be aware of, especially when you have more than one level of indirection.
Your first allocation, using this pattern, would look like this:
matriz = malloc (largo * sizeof *matriz);
and the second:
matriz[i] = malloc (ancho * sizeof *matriz[i]);
Note, that you never have to cast a void pointer (the return value of malloc()), and that the argument to the sizeof operator only needs parenthesis when it's a type name. When you get rid of the parenthesis, and place the quantity (ancho) before the sizeof operator, the result is an expression that is very clean and easy to understand. That is, of course, my personal opinion.

Your first malloc casts to a pointer of pointer's but that doesn't mean it is. If you look at your 2nd malloc you're allocating the same thing. So when you dereference matriz[i][z] you're dereferencing a charater, not a pointer. So I believe, it's been a while since I've done C, your first malloc needs to be (char**)malloc(sizeof(char*)*largo).

Related

How can you dynamically allocate a pointer in the form int (*p)[n] in C? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Suppose I get input from somewhere and store it in a variable. Pretend the variable is Cols.
I want to make an array in the form
int (*p)[Cols]
Now, I know you can't do this. So how would I dynamically allocate it to do it?
Teaching me how to do so would really be appreciated!
You can absolutely use int (*p)[Cols], it's a pointer to array of size Cols (Cols times size of int, in bytes), you just have to allocate memory for it, until you do, it doesn't point to a valid memory location. The constraint is that the allocated memory needs to be in blocks of multiples of Cols:
int (*p)[Cols] = malloc(sizeof *p); //prefered
Or
int (*p)[Cols] = malloc(sizeof(int) * Cols); //alternative
In both of the above expressions, supposing Cols's value is 10, p will point to a block of memory that can take 10 ints.
Usage:
for (int i = 0; i < Cols; i++)
{
p[0][i] = i;
}
The above expresssions only allocated space for one line of ints, but since p is a pointer to array, you can allocate space for as many of them as you want (given the memory constraints).
Let's assume you want an array with 5 lines and Cols columns:
int (*p)[Cols] = malloc(sizeof *p * 5);
Usage:
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < Cols; j++)
{
p[i][j] = i * j;
}
}
As you (probably) know this kind of construct is primarily used to emulate a 2D array, one of the advantages is that you can then free all the memory with a single free:
free(p);
Whereas constructs like an array of pointers, or a pointer to pointer would force you have multiple frees.
int (*p)[Cols] = malloc( sizeof *p * Rows );
allocates enough space for a Rows x Cols array of int and assigns the address of that array to p. You can then access each element as p[i][j].
To deallocate all you need is
free( p );

Segmentation fault when initializing 2D array in c [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am declaring a 2d array in a headers file like this : int **arr;
Then I'm allocating memory and I initialize it with zeros.
However I'm getting segmentation fault.
Here is my code :
arr = (int **)malloc(d * sizeof(int *));
for (int u=0; u<d; u++)
arr[u] = (int *)malloc(q * sizeof(int));
for(int i=0; i<d+1; i++)
{
for(int j=0; j<q+1; j++)
{
arr[i][j]=0;
}
}
d+1 and q+1 both outside the boundary.
Use d and q
If you want to initialize with zero use calloc() which is simple to use and reduces redundant operations
arr = (int **)malloc(d * sizeof(int *));
for (int u=0; u<d; u++)
scoreBoard[u] = (int *)calloc(q , sizeof(int));
This code will create 2d int array and initialize with zero
You are getting a segmentation fault because you are overstepping the array's bounds.
for (int i = 0; i < d + 1; i++)
Should become:
for (int i = 0; i < d; i++)
And similarly for the other one. Don't forget array indices go from 0 to 1 less than the size (in elements) of the array.
Also:
Was the memory for scoreboard allocated? Currently, you create an array called arr rather than for the scoreboard you are initializing, so scoreboard[u] may also be out of bounds regardless of the value of u.

Define a very large 2D array array with double type [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to define a 2D array with size 20*100000 in C. I do not want to keep the size fixed.
double **twod = malloc(20 * sizeof(double *));
int i;
if (twod == NULL)
abort();
for (i = 0; i < 20; ++i)
if ((twod[i] = malloc(100000 * sizeof(double))) == NULL)
abort();
// clean up
for (i = 0; i < 20; ++i)
free(twod[i]);
free(twod);
The first malloc call allocates space for 20 double pointers. Each double pointer will point to a subarray.
The second malloc call in the loop allocates 100000 doubles in each subarray.
The free calls do the inverse of malloc--they return memory to free store. First, each subarray must be freed, in a loop. Then the entire array itself must be freed too.
The return value of malloc is examined against NULL. If malloc returns NULL, then the system is out of memory. This is important since you are allocating HUGE amounts of memory. If malloc returns NULL, the application is aborted.
You'll need to define a pointer to pointer and initialize it like this:
int i;
double **array;
array = malloc(sizeof(double *)) * 20);
for (i=0; i<20; i++) {
array[i] = malloc(sizeof(double) * 100000);
}
Don't forget to free the memory when you're done with it.
You can use a Variable-length array (since C99) in order to avoid fragmentation:
double (*array)[cols];
array = malloc(sizeof(*array) * rows);
In this way calling free(array); is enough.

sort an array of strings in alphabetical in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
i have a linked list of srtings that i need to sort in alphabetical order
and i am tryping to copy the strings to an array and then sort and print them in alphabetical order
void DisplayAll(k *l,p *p)
{
int i,j;
p *temp;
temp = malloc(l->num*sizeof *temp);
for (i = 0; i < l->num; i++)
{
strcpy_s(temp[i].name, 20, p->name);
p = p->next;
i++;
}
for (i = 0; i < l->num - 1; i++){
for (j = i + 1; j< l->num; j++)
{
if (strcmp(temp[i].name, temp[j].name) > 0)
{
strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);
}
}
for (i = 0; i < l->num-1; i++){
printf("%s\n", temp[i].name);
}
}
this is the k struct and the p stuct
typedef struct p
{
char name[20];
struct p* next;
}p;
typedef struct k
{
int num;
p *head;
}k;
and i getting an Error evey time i run it
There's a couple of problems with your code:
First off: This doesn't look right at all:
strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);
according to the docs:
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
The first and last arguments are expected to be of the type char*. You've defined struct p .name as char[20], so temp->name[i] will be of type char.
I guess you're actually trying to do something like this:
//get struct p at offset i in temp, access member "name"
strcpy_s(temp[i].name, 20, temp[j].name);
Secondly: You're allocating memory for temp, but you fail to free it once you're done (ie when your function returns). You have, in other words, a memory leak. Sure, once your program exits, the memory is almost certainly going to be freed, but if you're writing programs that have to run for extended periods of time, and functions like this are getting called several times over, your memory consumption will gradually increase, and you don't want that to happen. In short, after your last loop (where you print everything out), add this:
free(temp);
Edit
You've added the free call now, and -correctly- wrap it in an if (temp). However: if malloc had returned a NULL pointer, don't you think you should've cought that at the beginning of the function?
temp = malloc(l->num * sizeof *temp);
if (!temp)
return;//or return int to indicate error or or exit EXIT_FAILURE; or something
There's no reason for you to reach the point where you free(temp) without having successfully allocated the memory.
Third: As #Bluepixy pointed out in his comment, there's a syntax error, too: the if (strcmp(temp[i].name, temp[j].name) > 0) branch is never closed properly: you're missing a closing bracket after the third strcpy_s call.
Lastly, you're allocating enough memory to accomodate l->num structs. You initialize them in such a way that every other struct will be assigned the name member of the next struct p in a list. You're not really making sure that p->next isn't a null pointer. This could cause problems (dereferencing a null pointer). So change the first loop into something like this:
int l_num = l->num;//you'll see why
for (i = 0; i < l_num; i+=2)//increment twice if you want/need to
{
strcpy_s(temp[i].name, 20, p->name);
p = p->next;
if (p == NULL)
{
l_num = i+1;//this is as far as we ought to go in the subsequent loops
break;//or handle error in some way
}
}
After this, replace all your ;i < l->num; conditions in your loops with i < l_num or j < l_num to avoid using uninitialized string values.
Just a final tip: If you're not working on anything too time critical, it might be useful to use calloc instead of malloc, especially when dealing with strings, or use memset(temp[i]->name, 0, 20); to ensure all char[] members are indeed empty strings.
If you find yourself using a lot of str* functions (strncat, strncpy and the like), even something as simple as temp[i]->name[0] = '\0'; can make life a lot easier.

Unable to properly free malloc of another malloc [duplicate]

This question already has answers here:
String assignment in C
(4 answers)
Closed 7 years ago.
Here's the snippet with issues.
int main()
{
char** RESERV = (char**)malloc(sizeof(char*)*4);
printf("%i, %i, %i, %i, %i", **RESERV, *RESERV, RESERV, &**RESERV, sizeof(char*));
int i;
for(i = 0; i < 4; i++)
{
RESERV[i] = (char*)calloc(sizeof(char),16);
RESERV[i][15] = '\0';
}
for(i = 0; i < 4; i++)
RESERV[i]="Iambananananananananananana";
for(i = 0; i < 4; i++)
printf("\r\n>%i<", RESERV[i]);
for(i = 0; i < 4; i++)
{
printf("\r\n<%i>", (RESERV[i]));
free(RESERV[i]);
}
free(RESERV);
}
This code free() is working fine in 32 bit , but somehow crashes horribly in 64 bit mode.
In my main program I've omitted freeing the members of the char** causing unexptected behavior every now and then, which I obviously do not want.
I've tried playing around with addresses and pointers, even tried
free(RESERV+(i*sizeof(char*))
Which failed too. Can someone clarify what I'm doing wrong?
In your code
RESERV[i]="Iambananananananananananana";
creates the problem. It overwrites the memory allocated by malloc(). Thus,
You face memory leak, because the malloc()ed pointer is lost.
You cannot call free() with the changed pointer. It invokes undefined behaviour.
Solution:
In C, you don't assign strings, instead, you can use strcpy() to get your work done.
Notes:
even in case of strcpy() you cannot use "Iambananananananananananana". In this case, it will create memory overrun as destination does not have enough memory to hold it completely.
Use proper format specifiers. in your printf() statements, most of the arguments to %i are not of type int. For pointer type arguments, you should be using %p, atleast. Otherwise, it will be UB.
RESERV[i]="Iambananananananananananana";
This is not the proper way to populate this string after allocating it. You are overwriting the value of that pointer.
strncpy(RESERV[i], "Iambananananananananananana", 15);
RESERV[i][15] = 0;
This is what you're looking for.
Notice, too, that you are apparently to assign something into that pointer that is larger than the memory that you have allocated.
The line
RESERV[i]="Iambananananananananananana";
is incorrect - You need to do
strncpy(RESERV[i], "Iambananananananananananana", 15);
RESERVp[i][15] = 0;

Resources