Segmentation Fault when allocating memory to a pointer to pointer variable [C] [closed]
Clash Royale CLAN TAG#URR8PPP
Segmentation Fault when allocating memory to a pointer to pointer variable [C] [closed]
I'm trying to represent an array of strings by using a pointer to pointer. So I've defined char** arr
as below:
char** arr
uint8_t lines = getLines();
char** arr = malloc (sizeof (char*) * lines);
// char** arr = malloc (sizeof (char*) * ROWS_COUNT);
In the debug process, the line above will be executed successfully and allocates memory to arr
. The problem (and so, the error) issues when trying to allocating enough memory to hold a string within *(arr + 0)
as below:
arr
*(arr + 0)
// #define PATH_MAX 4096
*arr = malloc (sizeof (char) * (PATH_MAX + 1));
Runtime Error:
Signal: SIGSEGV (Segmentation fault)
Note: I've used casting operators (the first assignment by char**
and the second one by char*
). It doesn't work too.
char**
char*
Note: I've used ROW_COUNTS
here for the sake of simplicity. In the original code, there is a lines
variable which I use instead of ROWS_COUNT
. lines
contains an uint8_t
value. (in my case, 3
)
ROW_COUNTS
lines
ROWS_COUNT
lines
uint8_t
3
This question appears to be off-topic. The users who voted to close gave this specific reason:
Those two lines won't cause a segfault (unless there's something strange going on with
ROWS_COUNT
or PATH_MAX
). Please post a Minimal, Complete, and Verifiable example.– user3386109
Aug 8 at 6:57
ROWS_COUNT
PATH_MAX
It's all; there are no more related lines to the subject. I've used ROW_COUNT here for simplicity. Actually, I'm using a variable named
lines
instead; which is containing the value of 3
. PATH_MAX
(which I think is system dependent) is a constant which defines the MAX path length on Linux systems.– noteworthy
Aug 8 at 7:02
lines
3
PATH_MAX
If
malloc
triggers a seg-fault, you've possibly corrupted your heap with some other code in the "hundreds of lines" prior to this allocation (quoting you from your comment in one of the answers below). With only what you've shown here, the best you can hope for are wags (wild-ass-guesses). This site isn't about guesses; it's about answers. Provide a Minimal, Complete, and Verifiable example or this question will likely be short-lived.– WhozCraig
Aug 8 at 7:26
malloc
And btw,
char (*arr)[PATH_MAX+1] = calloc(ROW_COUNT, sizeof *arr);
would seem much simple if you really are just looking to get ROW_COUNT
number of fixed char
buffer space. Unless you need independent string pointers for later replacement and freeing, I'd opt for that alternative; single-alloc; single-free.– WhozCraig
Aug 8 at 7:29
char (*arr)[PATH_MAX+1] = calloc(ROW_COUNT, sizeof *arr);
ROW_COUNT
char
2 Answers
2
You could dynamically allocate memory in single malloc()
, Try this code :-
malloc()
char (*arr)[ROWS_COUNT][PATH_MAX + 1] = malloc (sizeof(*arr));
and you could access strings using :-
(*arr)[ index ]
and characters using :-
(*arr)[ row ] [ column ]
Example :-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATH_MAX 4096
#define ROWS_COUNT 500
int main()
char (*arr)[ROWS_COUNT][PATH_MAX + 1] = malloc (sizeof(*arr));
strcpy((*arr)[400],"Hello World");
printf("n String : %s",(*arr)[400]);
printf("n Character : %c",(*arr)[400][2]);
Output :-
String : Hello World
Character : l
Sorry, I've forgotten to notice I'm using
ROWS_COUNT
for simplicity here. In the original code, I use a variable named lines
. (note added to the main post) BTW, it seems a good solution if someone using a constant name as the row counter.– noteworthy
Aug 8 at 7:46
ROWS_COUNT
lines
Note this will require sweeping changes to the remainder of the code that uses
arr
everywhere following this (arr
will have to be (*arr)
. The OP, at most, needs an array of arrays. Ex: char (*arr)[PATH_MAX+1] = calloc(ROW_COUNT, sizeof *arr);
– WhozCraig
Aug 8 at 7:54
arr
arr
(*arr)
char (*arr)[PATH_MAX+1] = calloc(ROW_COUNT, sizeof *arr);
@WhozCraig Sorry I missed
*
operator . I have changed to sizeof(*arr)
.– anoopknr
Aug 8 at 7:54
*
sizeof(*arr)
@anoopknr It's still not necessary to have both dimensions subscripted to get a single allocation.
– WhozCraig
Aug 8 at 7:55
// #define PATH_MAX 4096
*arr = malloc (sizeof (char) * (PATH_MAX + 1));
I think this line needs to be within a loop of ROWS_COUNT
times. So that memory can be allocated for all the rows to be stored.
ROWS_COUNT
Tested on MAC with Xcode (Version 9.3 (9E145)), working fine:
char** arr = (char**) malloc (sizeof (char*) * 1000);
int i = -1;
while(++i < 1000)
*(arr + i) = (char*) malloc (sizeof (char) * (PATH_MAX + 1));
BTW, On the first loop (let's say i = 0), the same statement must be executed. (which leads to an error)
– noteworthy
Aug 8 at 7:04
@noteworthy - I am on a MAC with xcode, Just tested the code that I have added in the answer to preserve formatting. This code works fine. Also I noticed that PATH_MAX is defined as 1024 in syslimits.h.
– Rizwan
Aug 8 at 7:12
i
goes from 1
to 1001
in the loop body of your example, which is an off by 2 error and does not initialize the first element.– mch
Aug 8 at 7:25
i
1
1001
You should use a for loop instead of that icky while loop.
for(size_t i=0; i<1000; i++) arr[i] = malloc(...);
That way you also remove the off-by-one bugs you have written in the current code: *(arr + 1000) =
writes out of bounds of the array.– Lundin
Aug 8 at 7:29
for(size_t i=0; i<1000; i++) arr[i] = malloc(...);
*(arr + 1000) =
"Less keystrokes" is a horrible rationale for writing an algorithm in a certain way. Programming is all about hitting a whole lot of keys on the keyboard. If that's not your thing, then programming isn't for you.
– Lundin
Aug 8 at 10:07
This seems OK, can you post more code ?
– Filip Kočica
Aug 8 at 6:56