Quote:
Originally Posted by Daffy
When I enter a name (for example in 'artist') and it has 40 characters, taglist.artist stores it properly (with malloc() ).
|
Not from the code posted. From above:
Code:
printf("Enter artist name:\n");/* ask for input, read to array, remove enter */
char *artist = (char*) malloc(50 *sizeof(char));
fgets(taglist.artist, LEN, stdin);
remove_enter(taglist.artist);
Here,
artist gets 50 bytes of heapspace
(assuming a character is represented in one byte...) through
malloc(), & then nothing is done with the heapspace until it is freed at the end of
main(). Any keyboard entry is read directly into the global structure instance which was fully defined at compile-time.
Recognize that the name
"artist" is being used in two completely different contexts. One, naming a field within a global structure. The other, a variable defined within
main(). To illustrate, study the following example:
Code:
$ cat addresses.c
#include <stdio.h>
struct struct_name {
int foo;
} global_sn_instance;
int main()
{
struct struct_name sn_instance;
int foo;
printf("global struct:\t%u\n", (void*) &global_sn_instance.foo);
printf("local struct:\t%u\n", (void*) &sn_instance.foo);
printf("local variable:\t%u\n", (void*) &foo);
return 0;
}
$ gcc addresses.c
$ a.out
global struct: 1006645888
local struct: 3485315520
local variable: 3485315516
$
The addresses of each
"foo" is
different.
Quote:
The problem is when I pass the value in char *command[LEN], it stores only the 30 first characters.
|
I suspect you are using code which has not been posted as the last example above, only the artist & track name are being initialized from keyboard input. My recommendation would be add
printf() statements after each keyboard entry such that you can verify how input is getting copied about. I would also suggest dumping all elements in your constructed
command variable before spawning the child process. These are debugging aides which can be taken out later if desired.
Quote:
Do I need to use malloc() on every array object?
|
There are two ends to this continuum. Either the
entire structure could be allocated from heapspace
(memory grabbed at runtime...), or individual fields. Consider the following example:
Code:
$ cat memory.c
#include <stdio.h>
#include <stdlib.h>
struct a {
char *s;
};
struct b {
char s[8];
};
int main()
{
struct a a;
struct b *p;
a.s = (char*) malloc(8 * sizeof(char));
scanf("%s", a.s);
p = (struct b*) malloc(sizeof(struct b));
scanf("%s", p->s);
printf("a:\t%s\n", a.s);
printf("b:\t%s\n", p->s);
free(a.s);
free(p);
return 0;
}
$ gcc memory.c
$ a.out
abc
xyz
a: abc
b: xyz
$
Note that I used the word
"continuum". Stranger scenarios can exist, but the code gets further twisted. At this point, you should be making sure you understand the basics before getting too exotic.
Quote:
And a last question for free(). When I use it on a char object inside a structure, I target it by name (for this example free(artist)) or by first referring to the structure name (free(taglist.artist))? Is it a good solution to free after use the entire structure by free(taglist)?
|
free() should
only be called on addresses which have been allocated through
malloc() or any of its relatives. Calling
free() on anything which has not been allocated through
malloc() (or its relatives...) could very well send execution into the weeds. It all depends upon how heapspace management is written for the specific processor. On some platforms, it may work for any pointer. Others, it won't. The processor agnostic answer is to only call
free() on objects previously allocated on the heap.