1

Ok, here's some overview about what I'm trying to achieve. I want the user to be able to enter any amount of strings, and then I want to save those strings in a double char pointer. At the moment I haven't dealt with scaling my memory allocation for my double char pointer because I want to get it working first.

char **list = malloc(sizeof(char*)*5);

for(i = 1; i < argc; i++) {
        strcpy(list[i], argv[i]);
}

I honestly thought this was going to be simple, so hopefully I'm making some stupid mistake. I keep receiving a seg fault error at the strcpy function.

a ad
  • 21
  • 2
  • 1
    You allocated space for the pointers, but you didn't allocate space for the pointers to point to, nor did you set them to point to the space you didn't allocate. – Seth Carnegie Mar 16 '12 at 00:56

3 Answers3

3

What you did is only allocated memory for array of pointers to strings (which is correct), but you also need to allocate memory for each string in your array:

First (simpler) option:

char **list = malloc(sizeof(char*) * argc);
for(i = 1; i < argc; i++)
{
    list[i] = strdup(argv[i]);
}

second (more complex) option:

size_t n = 0;
char **list = malloc(sizeof(char*) * argc);
for(i = 1; i < argc; i++)
{
    n = strlen(argv[i]) + 1;
    list[i] = malloc(n);
    strcpy(list[i],argv[i]));
}
sirgeorge
  • 6,331
  • 1
  • 28
  • 33
  • 3
    `sizeof(char)` is 1. Why bother writing it? – Carl Norum Mar 16 '12 at 01:03
  • If you understand that then you do not have to bother, but from his post you can see clearly that he does not understand many things in C yet, so it makes my intensions clear(er). – sirgeorge Mar 16 '12 at 01:06
  • Hm. I feel the opposite - that the use of `sizeof(char)` indicates a lack of understanding of how the language works. – Carl Norum Mar 16 '12 at 01:07
  • The strdup works like a charm! Thank you. I tried these other options too and I still was receiving segfaults...weird. I'll have to mess with it more. – a ad Mar 16 '12 at 01:08
  • 2
    @Carl Norum: It is not about language at all, it (may be) about platform. The C standard does not specify that sizeof(char) is always one, but it does specify what range of values it must be able to store. There are platforms where sizeof(char) is not one. (There is at least one post about it somewhere). – sirgeorge Mar 16 '12 at 01:12
  • **WRONG.** sizeof(char) is **always** 1. *Always*. From the spec: "[The **`sizeof`** operator,] when applied to an operand that has type **`char`**, **`unsigned char`**, or **`signed char`**, (or a qualified version thereof) the result is 1." – Carl Norum Mar 16 '12 at 01:14
  • 1
    I believe it's just good practice to use sizeof(char)...just my two cents. When you have programmers of all different levels reading your code, specifying char as opposed to 1 makes things clearer. Otherwise someone like me wouldn't understand where the 1 came from. Though I can see how it might be appealing to stroke one's ego by explaining every nuance to lesser experienced programmers rather than writing concise code. – a ad Mar 16 '12 at 01:17
  • @a ad - seriously? Do you explicitly typecast your `char` variables up to `int` before you do arithmetic on them too? As to not using `sizeof(char)`, you don't have to replace it with `1`. You're multiplying by it - multiplying by one is a no-op. – Carl Norum Mar 16 '12 at 01:18
  • About this sizeof(char): This is (unfortunately) typical almost religious argument raised by C programmers (another example is casting/not casting result of malloc). The C programmers LOVE to have everything done/converted/promoted implicitely. If you do something explicitely - then it is a bad practice in their opinion. – sirgeorge Mar 16 '12 at 01:24
  • Casting the return value of `malloc()` can hide *real bugs* in code. How can doing it be good practice? I'm not going to disagree that there are plenty of people who are just trying to look smarter than everyone else, but writing idiomatic code is an important part of programming in *any* language. – Carl Norum Mar 16 '12 at 01:28
  • There is a big post and discussion about it here: http://stackoverflow.com/a/605858/19410. The guy makes four points about it, and all of them (except the one) are really matter of your preference. And in the important one (about ) he is WRONG (it does not matter if you cast or not - if you did not include the header - you get warning: "implicit function" - if you ignore/produce warnings - it is your problem). Sorry, I'm not going to continue this religious debate. – sirgeorge Mar 16 '12 at 01:37
0

You've allocated an array of pointers to strings, but you haven't allocated any space for the strings themselves. Every time you call strcpy(), you're passing it an uninitialized destination pointer. Add a line to the beginning of your loop:

list[i] = malloc(strlen(argv[i]) + 1);

If you want it to work for any number of strings, your initial allocation has to be:

char **list = malloc(sizeof(char *) * argc);
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
0

It's not correctly malloced you only malloced the main pointer not the other ones.

Try this

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char **argv) {
    char **list = malloc(sizeof(char*)*argc);
    int i;    
    for(i = 0; i < argc-1; i++) {
       list[i] = malloc(sizeof(char) * (strlen(argv[i+1]) + 1));
       strcpy(list[i], argv[i+1]);
       printf("%s\n", list[i]);
    }
return 0;
}

EDIT I forget the v in argv

EDIT (working copy edited above) output below

./temp hello this is a list of arguments
hello
this
is
a
list
of
arguments
twain249
  • 5,666
  • 1
  • 21
  • 26