Reputation: 60
I think I've got everything fixed now. I made the mistake of incrementing the environ variable instead of treating it like an array and iterating across it. The following is what I have now and it should be good to go.
extern char **environ;
int main(int argc, char *argv[]) {
// determine number of environment variables
int n = 0;
char *c = NULL;
while ((c = environ[n++]) != NULL) {
printf("%s\n", c);
}
printf("%s\n%d\n\n", c, n);
// allocate array to store character pointers to environment array
char **new_c;
printf("This prints\n");
if ((new_c = malloc(n * sizeof(*c))) == NULL) {
printf("Error\n");
exit(EXIT_FAILURE);
}
printf("This prints now too\n");
free(c);
// sort array of character pointers
// parse each environment variable and output
exit(0);
}
To start, I've read through a couple dozen malloc & segmentation fault questions on here and none seem to be the same as mine. That being said, if this is a duplicate question would you mine pointing me to the solution?
Hi all, I'm having a problem using malloc. I compiled and ran my program once and malloc worked. I then began filling in more code to solve the problem and since that first run I have received a Segmentation Fault. Below is my code in it's last working state (still giving a seg fault error though):
extern char **environ;
int main(int argc, char *argv[]) {
// determine number of environment variables
int n = 0;
char *c = *environ;
while ((c = *environ++) != NULL) {
n++;
printf("%s\n", c);
}
printf("%s\n%d\n\n", c, n);
// allocate array to store character pointers to environment array
printf("This prints\n");
if ((c = malloc((size_t) n)) == NULL) {
perror("Unable to allocate memory\n");
}
printf("This does not print\n");
free(c);
// sort array of character pointers
// parse each environment variable and output
exit(0);
}
The program is supposed to allocate memory for a char array that will then be used to sort, parse, and print the name-value or value-name pairs depending on what the FORMAT value is set to. The first loop works and iterates through the environ variable and prints out each name-value pair. The two printf statements I included state what I see in the terminal. Does anyone have any ideas what I'm doing wrong?
Also, I have tried using the following malloc lines:
char *new_c = malloc((size_t) n);
char *new_c = malloc(n);
char *new_c = malloc(1);
char *new_c = malloc(sizeof(n));
int *ptr = malloc((size_t) n);
There are probably a few others I tried but I'm still baffled. There are so few lines of code that I'm not sure how I could be messing anything up this early on. Also, for giggles here's what I get when I use free in the terminal (showing I have memory available):
total used free shared buff/cache available
Mem: 3036836 1404340 902852 104712 729644 1491248
Swap: 0 0 0
I've also tried calling malloc outside of the if statement as such:
c = malloc((size_t) n);
if (c == NULL) {
perror("Unable to allocate memory\n");
}
Upvotes: 2
Views: 4507
Reputation: 25908
Two things with this:
if ((c = malloc((size_t) n)) == NULL) {
perror("Unable to allocate memory\n");
}
You are allocating n
bytes, here. It sounds like you want to allocate space for n
pointers to char
, so you should replace with:
malloc(n * sizeof(char *))
If this is indeed what you're trying to do, then c
should be char **
, not char *
, and better still would be:
c = malloc(n * sizeof *c)
Incidentally, you appear to be using c
for two completely different things. It's generally better not to do this with variables - since it makes your program harder to understand - and instead to use one variable to loop through to print your environment variables, and a different one to store your dynamically allocated array.
Also, you call perror()
if malloc()
fails, but then you just continue right on with your program as if there was no error. You should actually respond to a failure of this nature, if nothing else by calling exit(EXIT_FAILURE)
after reporting it.
Upvotes: 1
Reputation: 18410
Here you are modifying the global environ
:
while ((c = *environ++) != NULL) {
After the while loop, environ
points to uninitialized memory.
malloc()
looks for some environment variables which can modify its behaviour and is now dereferencing a pointer to uninitialized memory.
Use this:
int i = 0;
while ((c = environ[i++]) != NULL) {
This should fix the segmentation fault.
Upvotes: 3