GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 27-Mar-2005, 14:03
ronin ronin is offline
New Member
 
Join Date: Mar 2005
Posts: 6
ronin is on a distinguished road

problem modifying an array of char in a function


Hi all, Im new to the forums so hope to not break any rules posting this question here, im almost sure this havent asked before in previous threads but if thats the case please redirect me to that thread and close this one

well my problem is that im trying to modify a char* var already declared and initialized in the main, so the thing im not sure is about the arguments that should be in function prototype, i have tried all the possibilities i could have thought but of course i missed one. To avoid floodfill this with tons of lines from the sources i´ll post the simplest function that illustrates my problem
CPP / C++ / C Code:
void myfunction(char *a)
{
	a[2]='g';
}

this actually causes a bad program ending, i know i can use [] instead of * and will work but it wont if i want to use a dynamic array, so anyone can help me here? please
  #2  
Old 27-Mar-2005, 15:51
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
prototype for the function in your post would be

CPP / C++ / C Code:
void myfunction(char *);

char array in C is same as pointer to char. You can use either pointer notation or array notation when passing an char array to the function. In C arrays are always passed by reference and not by value.

You can use any notation interchangably. Both are valid. Its justs programmer's convenience. Experience programmers usually use pointer notations.

Following code snippet may give you some idea. I have two functions that work on char array. One function changes the first character in array to uppercase while other function changes in back to lowercase. I am using pointer and array notation interchangably in the function prototypes. Function "modifyname1" takes char pointer as an argument but I can pass a char array to it and vice-versa with "modifyname2" function. Either way, they work and does the job they are supposed to do.



CPP / C++ / C Code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

/*Function prototypes*/
void modifyname1 (char *);
void modifyname2 (char []);

int main()
{
	char name1[10];
	char *name2;

	printf("\nEnter name1: ");
	scanf("%s",name1);

	name2= (char *)malloc(10);

	printf("\nEnter name2: ");
	scanf("%s",name2);

	modifyname1(name1);
	printf("\nModified name1 with function modifyname1: %s\n",name1);	  
	modifyname1(name2);
	printf("\nModified name2 with function modifyname1: %s\n",name2);

	modifyname2(name1);
	printf("\nModified name1 with function modifyname2: %s\n",name1);	  
	modifyname2(name2);
	printf("\nModified name2 with function modifyname2: %s\n",name2);

	return 0;
}

void modifyname1 (char name[])
{
	name[0]=toupper(name[0]);
}

void modifyname2 (char *name)
{
	*name = tolower(*name);
}


Following is the program output
Quote:
$ ./arr1.exe

Enter name1: james

Enter name2: bond

Modified name1 with function modifyname1: James

Modified name2 with function modifyname1: Bond

Modified name1 with function modifyname2: james

Modified name2 with function modifyname2: bond

  #3  
Old 27-Mar-2005, 17:32
ronin ronin is offline
New Member
 
Join Date: Mar 2005
Posts: 6
ronin is on a distinguished road
Thanks a lot for your help Nkhambal, I think i was messing things in my head thinking that once I have a prototype with [] i should stick to fixed dimension arrays, your snippet really showed what i have been looking for many hours today, really thank you. And it helped me spot a thing that wasnt working in my code, as i said I had the array declared and initialized but i was doing this way

CPP / C++ / C Code:
char *a="James Bond";

instead of doing the way you did

CPP / C++ / C Code:
char *a;
a=(char *)malloc(11);
strcpy(a,"James Bond");

the thing is i was thinking first method was ok and legal but for some reason that was causing a bad program ending, using your method works perfect, but i still want to know, do you know why is that so? I think i read somewhere using first method of initialization means the compiler frees memory for you to put the string plus the termination character... and even printing the string is ok, so can you tell me where is the difference?
  #4  
Old 27-Mar-2005, 18:25
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
when you define a char pointer variable, no memory is allocated to it. Its your responsibilty to allocate required amount of memory before storing any value to it. When you use char array, a predefined amount of memory is allocated to it. You need not allocate it at run time.

Although, following statement,

CPP / C++ / C Code:
char *a="James Bond";

is syntactically correct and will not produces any errors during compilation, it will fail at runtime because "a" does not have its own allocated memory, hence points nowhere or rather points to someone else's memory space. When you try to write string "James Bond" into it, you are trying to access a memory which does not actually belonging to "a". This is a problem and your program will crash with core dump or segmentation fault.

The solution to this problem is, allocate required amount of memory to "a" first (using malloc()) and then store something into it. Also, while working with char pointers or strings in C, we should make sure that, we always allocate 1 extra byte of memory than the actual size we want, to store the "null" or ' \0 ' termination at the end of the string. If you string is not properly null terminated, reading or performing other operations on string will produces unexpected results or even crash sometimes. Standard string functions such as strcpy or strlen rely on properly terminated string to work correctly. strcpy() null terminates the destination string after copying source string into it. Hence it is must you have an extra byte available in destination string for it to do that.
  #5  
Old 27-Mar-2005, 18:56
ronin ronin is offline
New Member
 
Join Date: Mar 2005
Posts: 6
ronin is on a distinguished road
thanks so much again, so i have everything wrong in my head, I still have a lot to learn, I´ll follow what you said and always allocate memory first when dealing with pointers, keeping in mind the null character should be included in the ammount of memory I request. Thanks for all your help
  #6  
Old 27-Mar-2005, 21:39
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
Read more on pointers. All types of pointers. Also, you need not use malloc() everytime with pointers. Some functions in C library returns a pointer to the memory they allocate internally. For e.g. string functions strdup() and strdp2(), which duplicates a string. They return a new pointer to the memory location they internally allocate. For e.g.

Consider following program:
CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	const char *name3 = "James Bond";
	char *name4;

	name4 = strdup(name3);

	printf("\nName4: %s\n", name4); 

	free(name4);

	return 0;
}

Following is the output when you run it.

Quote:
$ ./arr2.exe

Name4: James Bond

As you can see, I did not allocate memory for char pointer name4. Why ? Cause strdup() internally allocated memory using malloc() and returned a pointer to that memory after copying the string stored in "name3" into it. Thus, "name4" need not allocate memory. It now simply points to the memory allocated by strdup(). But now it becomes our responsibility to free the memory allocated by strdup(). Freeing allocated memory is another important operation one must do, when dealing with pointers. Otherwise, your program would cause a memory leak (take up system memory without releasing it). Ideally, every malloc() or calloc() should have corresponding free() associated. Remember to return what you take.

Good luck.
  #7  
Old 28-Mar-2005, 14:43
ronin ronin is offline
New Member
 
Join Date: Mar 2005
Posts: 6
ronin is on a distinguished road
Thanks I´ll try getting a better knowledge on pointers and all you mentioned, and I see you example illustrates a way of not allocating memory since the function itself allocates it internally, never used strdup before but its as you said, hmm... but, in that code you posted isnt name3 using a memory that havent been requested before? I know this works fine but according to what you said yesterday even though name3 stores the name and it can be displayed etc that memory area havent been allocated.... or am i totally wrong?
  #8  
Old 28-Mar-2005, 16:10
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
name3 is contant string (or readonly). It is allocated memory when its initializeded this way. This is an exception.

Thanks,
  #9  
Old 28-Mar-2005, 16:49
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,712
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by nkhambal
name3 is contant string (or readonly). It is allocated memory when its initializeded this way. This is an exception.

Thanks,

It is not an exception.

name3 is a pointer to char. Its value is initialized to the address of the string literal somewhere in memory.

strdup(name3) allocates enough storage to hold a copy of whatever string that name3 is pointing to, performs the copy, and returns the address of the copied string.

Regards,

Dave
  #10  
Old 28-Mar-2005, 17:08
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
Yes my bad. Turns out I need a little brush up.

Ronin, the following statement you had earlier, should work normally, when used this way.

CPP / C++ / C Code:
/*Scenario 1*/
char *a="James Bond";
printf("%s",a);

It will fail in following scenario

CPP / C++ / C Code:
/*Scenario 2*/
char *a;
strcpy (a, "James Bond"); /*copy without malloc. Illegal. Program will crash*/;

I guess, I was wrong in giving you that explaination in first paragraph in my post for the "Scenario 1" above . My apology. However, Everything in that post is correct for "Scenario 2".
 
 

Recent GIDBlogToyota - 2008 September Promotion by Nihal

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Airport Log program using 3D linked List : problem reading from file batrsau C Programming Language 11 29-Feb-2008 07:44
[Include] Doubly-linked List dsmith C Programming Language 6 14-Apr-2006 13:12
Compiling Errors ToddSAFM C++ Forum 22 18-Dec-2004 11:42
Revising Script style ?????? pepee MySQL / PHP Forum 4 14-Apr-2004 04:59

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 11:19.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.