1

I have a program that asks to input two arguments using argv and I would like to then using the length of argv[1] and argv[2] dynamically allocate memory for two pointers to char inside my struct equal to the size of argv[1] and argv[2].

Here is my code but I'm not sure if I did it correctly, can anyone verify? Parameters passedargv1 and passedargv2 inside the function are argv[1] and argv[2] passed from the main() function. Basically I want to make chararray1=argv[1] and chararray2=argv[2] as if they were just plain char arrays, but I don't know ahead of time the size of our input so I can't pre-initialize chararray2 and chararray2. Also, I can't change what is inside argv, so i cannot have chararray1 and chararray2 just point to them because I will need to change them later on.

struct StructInformation{

    char *chararray1;
    char *chararray2;
};



typedef struct StructInformation SimplifiedStruct;

SimplifiedStruct *CreateMem(char *passedargv1, char *passedargv2) {

SimplifiedStruct *ptr=(SimplifiedStruct*)malloc(sizeof(SimplifiedStruct));
ptr->chararray1=(char*)malloc(sizeof(passedargv1));
ptr->chararray2=(char*)malloc(sizeof(passedargv2));
3
  • 1
    This gets significantly simpler if you're on a POSIX or XOPEN compliant system with strdup() and stop casting malloc() results Commented Sep 14, 2013 at 4:48
  • oh my bad i'll fix that thank you. But what about sizeof(passedargv1) is that okay or do i need to make it &passedargv1 because it is a pointer? Commented Sep 14, 2013 at 4:48
  • That doesn't work. sizeof(passedargv1) should be 4 or 8 byte (assuming a 32 or 64 bit system). Even when you dereference it, it wouldn't work since the sizeof() argument is calculated at compile time. As @WhozCraig suggested, strdup() is probably your best bet. Commented Sep 14, 2013 at 4:52

2 Answers 2

2
  1. Don't cast the return from malloc()

  2. malloc(char*)malloc is obviously wrong.

  3. For your main issue, sizeof(passedargv1) and sizeof(passedargv2) both just evaluate to sizeof(char *), so no, you have not done it correctly. You'll need to call strlen() on your two arguments, and add 1 to each, that'll tell you how much memory you need to allocate, presuming you just want to copy in the strings.

For instance:

ptr->chararray1 = malloc(strlen(passedargv1) + 1);
ptr->chararray2 = malloc(strlen(passedargv2) + 1);

and then presumably:

strcpy(ptr->chararray1, passedargv1);
strcpy(ptr->chararray2, passedargv2);

Don't forget to check the return from malloc() to make sure you got your memory.

Sign up to request clarification or add additional context in comments.

6 Comments

For 1. you mean (SimplifiedStruct*) and (char*)? I thought that was needed for type safety issues as creating memory doesn't know what type to return. 2. fixed, thank you. 3. so you mean i should do something like sizeof(strlen(passedargv1)+1)?
@user2778481: 1 - yes, that's what I mean. You've been misinformed. It's necessary in C++, and used to be necessary in C many years ago, but for modern C it's just bad, and hurts type safety rather than helps it. 3. Not quite, see edit.
Ah i understand, 1 char is 1 byte so it gives the correct memory space. Thank you.
@user2778481: Correct, sizeof(char) is 1 by definition.
If i free the struct will the memory allocated from the two char pointers inside the struct also be freed or will i have to do that seperately?
|
0

Replace sizeof with strlen and remember to include string.h. Because the size of a pointer always equals 4. And there is no need to use a cast when calling malloc.

ptr->chararray1 = malloc(strlen(passedargv1) + 1);
ptr->chararray2 = malloc(strlen(passedargv2) + 1);

EDIT:
Prototype of malloc:
void* malloc (size_t size); It returns a pointer of void* which can be cast to the desired type of data pointer in order to be dereferenceable. Since you have already defined chararray1 and chararray2 as char*, casts can be omitted.

3 Comments

You need to add 1 for the terminating '\0'.
The sizeof a pointer is not always 4. On 64 bit machines it's 8 and there may be even other exotic machines having different pointer sizes.
You actually do need to cast void pointers if you want to dereference them or access their members without the aid of a pointer variable of the correct type, I think this is what he means. For example, the cast is necessary in: char * my_func(void * ptr) { return ((struct StructInformation *) ptr)->chararray1; } even though it would be pretty silly to use a void pointer in the first place in this particular example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.