LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 01-31-2007, 10:30 AM   #1
adymroxx
Member
 
Registered: Mar 2005
Location: Iowa
Distribution: Fedora Core 9
Posts: 41

Rep: Reputation: 15
Disappearing Strings in C


I'm working on a simple shell program as part of a class project and I've hit a dead end. I'm new to C programming, so I could be missing something pretty obvious here, but I have pinpointed it to a certain chunk of my code. In the following snippet, the first for loop prints off all of the paths in the user's ENV path variable. In the second loop, it does the same only this time it tacks on a "/" character.

---snippet---
char *lookupPath(char **argv, char **dir) {

char *temp;

/* Not sure if the following line is necessary... */
temp = (char *) malloc(MAX_PATH_LEN * 2);
/* Print user's path variables */
for (i = 0; i < 8; i++) printf("%d= %s\n", i, dir[i]);
/* Look in PATH directories */
/* Use access() to see if the file is in a dir */
for (i = 1; i < MAX_PATHS; i++) {
temp = NULL;
if (dir[i] == NULL) continue;
temp = dir[i];
strncat(dir[i], "/", MAX_PATH_LEN);
printf("Looking %d in %s\n", i, temp);
.
.
.
}
---end snippet---

This is what prints:
---script---
$ ./shell
# ls
0= (null)
1= /usr/kerberos/bin
2= /usr/lib/ccache
3= /usr/local/bin
4= /usr/bin
5= /bin
6= /usr/X11R6/bin
7= /home/adam/bin
Looking 1 in /usr/kerberos/bin/
Looking 2 in /
Looking 3 in /usr/local/bin/
Looking 4 in /
Looking 5 in /bin/
Looking 6 in /
Looking 7 in /home/adam/bin/
---end script---

For reasons unbeknowest to me, only the odd numbered paths are printing.
One second dir[i] contains a path, the next moment it's null. Where are
my paths going??

Thanks in advance!
 
Old 01-31-2007, 11:31 AM   #2
kaz2100
Senior Member
 
Registered: Apr 2005
Location: Penguin land, with apple, no gates
Distribution: Debian testing woody(32) sarge etch lenny squeeze(+64) wheezy jessie
Posts: 1,455

Rep: Reputation: 85
Hi,

#1, Your first loop and second loop, initial value and loop condition are not same.
#2. It seems that you want to add "/" at the end of dir[i], (issue hiding here, potentially HUGE.) and screwing up succeeding member.

Your penguin will do what you ask...

Adding "/" to dir[n] is DANGEROUS, unless you know you have allocated free space after dir[n], which
Code:
char *lookupPath(char **argv, char **dir)
implies "NO, you do not". You may be overwriting first byte of next member or something else. (it depends on complier implementation.) C compiler usually does not detect it, as it trusts you. This may end up with run time error "Segmentation Fault"

Happy Penguins!

Last edited by kaz2100; 01-31-2007 at 11:45 AM.
 
Old 01-31-2007, 11:44 AM   #3
adymroxx
Member
 
Registered: Mar 2005
Location: Iowa
Distribution: Fedora Core 9
Posts: 41

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by kaz2100
Hi,

#1, Your first loop and second loop, initial value and loop condition are not same.
#2. It seems that you want to add "/" at the end of dir[i], (another issue hiding here, potentially HUGE), and printing out temp.

These two issues are a kind of forgettable, tiny and benign. Your penguin will do what you ask...

Adding "/" to dir[n] is DANGEROUS, unless you know you have allocated free space after dir[n], which
Code:
char *lookupPath(char **argv, char **dir)
implies "NO, you do not". You may be overwriting first byte of next member or something else. (it depends on complier implementation.) C compiler usually does not detect it, as it trusts you. This may end up with run time error "Segmentation Fault"

Happy Penguins!
Shouldn't this line
Code:
temp = (char *) malloc(MAX_PATH_LEN * 2);
give enough room to add "/" to the previous string? Keep in mind that I'm pretty new to C... should I call malloc once in each loop?

Thanks again
 
Old 01-31-2007, 11:49 AM   #4
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
I think that your problem lies with the adding the / to dir rather than another variable you so carefully set up and forgot to use.
dir is an array of strings and the memory will look as follows:
Code:
0/usr/kerberos/bin0/usr/lib/ccache0/usr/local/bin0/usr/bin0/bin0/usr/X11R6/bin0/home/adam/bin
^^dir[1]           ^               ^              ^        ^    ^              ^
dir[0]             dir[2]          dir[3]         dir[4]   dir[5]dir[6]        dir[7]
Where 0 is teh NULL character. Now when you add a slash to the end of dir[1] your new memory will be as follows:
Code:
0/usr/kerberos/bin/0usr/lib/ccache0/usr/local/bin0/usr/bin0/bin0/usr/X11R6/bin0/home/adam/bin
^^dir[1]           ^               ^              ^        ^    ^              ^
dir[0]             dir[2]          dir[3]         dir[4]   dir[5]dir[6]        dir[7]
And so dir[2] points to a NULL character.
 
Old 01-31-2007, 12:02 PM   #5
eddiebaby1023
Member
 
Registered: May 2005
Posts: 378

Rep: Reputation: 33
I think dir is an array of pointers to strings. We don't see all the code in the second loop - are you incrementing i within the loop as well as in the for line?
 
Old 01-31-2007, 12:10 PM   #6
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
dir is essentially argc
 
Old 01-31-2007, 12:17 PM   #7
adymroxx
Member
 
Registered: Mar 2005
Location: Iowa
Distribution: Fedora Core 9
Posts: 41

Original Poster
Rep: Reputation: 15
The entire function is as follows:
Code:
char *lookupPath(char **argv, char **dir) {
	/* This function searched the directories identified by the dir
	 * argument to see if argv[0] (the file name) appears there.
	 * Allocate a new string, place the full path name in it, then
	 * return a string. */
	char *result;
	char *temp;
	int  i;

	/* Check to seee if file name is already an absolute path */
	if (*argv[0] == '/') {
		result = argv[0];
		return result;
	}

	temp = (char *) malloc(MAX_PATH_LEN * 2);

	for (i = 0; i < MAX_PATHS; i++) printf("%d= %s\n", i, dir[i]);
	/* Look in PATH directories */
	/* Use access() to see if the file is in a dir */
	for (i = 0; i < MAX_PATHS; i++) {
		temp = dir[i];
		if (dir[i] == NULL) continue;
		temp = dir[i];
		strncat(temp, "/", MAX_PATH_LEN);
		//strncat(temp, argv[0], MAX_PATH_LEN);
		printf("Looking %d in %s\n", i, temp2);
		//if (access(dir[i], X_OK) == 0) {
		//	result = temp;
		//	return result;
		//}
	}
	/* File name not found in any path variable */
	fprintf(stderr, "%s: command not found\n", argv[0]);
	return NULL;
}
I've changed the strncat to add to the temp variable rather than dir[i] and the problem persists.

Last edited by adymroxx; 01-31-2007 at 12:26 PM.
 
Old 01-31-2007, 12:23 PM   #8
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Okay, that is because you do temp = dir[i], so temp points to where dir[i] points to, you need to copy dir[i] into temp then you should be alright.
 
Old 01-31-2007, 12:34 PM   #9
adymroxx
Member
 
Registered: Mar 2005
Location: Iowa
Distribution: Fedora Core 9
Posts: 41

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by graemef
Okay, that is because you do temp = dir[i], so temp points to where dir[i] points to, you need to copy dir[i] into temp then you should be alright.
That seems to work! Within the second for loop I now have
Code:
	for (i = 0; i < MAX_PATHS; i++) {
		if (dir[i] == NULL) continue;
		temp = (char *) malloc(MAX_PATH_LEN * 10);
		strcpy(temp, dir[i]);
		strncat(temp, "/", MAX_PATH_LEN);
		strncat(temp, argv[0], MAX_PATH_LEN);
		printf("Looking %d in %s\n", i, temp);
I know MAX_PATH_LEN * 10 is too big, but I'll round it down to the correct size later.

Thank you all for your help!
 
Old 01-31-2007, 12:39 PM   #10
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Great stuff
 
Old 01-31-2007, 12:39 PM   #11
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,154

Rep: Reputation: 333Reputation: 333Reputation: 333Reputation: 333
<curmudgeon>
It's problems like this -- memory allocation and pointers -- that made me decide, many years ago when I was a programming group manager, that the first programming course any programmer should list in their resume had to be an assembly language course. Anyone without that qualification had to work really hard to convince me to hire them.

I sometimes, but rarely, made exceptions for programmers with bcpl experience for non-trivial applications.
</curmudgeon>
 
Old 01-31-2007, 02:51 PM   #12
kaz2100
Senior Member
 
Registered: Apr 2005
Location: Penguin land, with apple, no gates
Distribution: Debian testing woody(32) sarge etch lenny squeeze(+64) wheezy jessie
Posts: 1,455

Rep: Reputation: 85
It seems that adymroxx learned step ZERO in C programming. Now, adymroxx cannot use "I am new in C" excuse any longer.
 
Old 01-31-2007, 10:44 PM   #13
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Quote:
Originally Posted by PTrenholme
<curmudgeon>Anyone without that qualification had to work really hard to convince me to hire them.
Guess I wouldn't of got hired then...
 
  


Reply

Tags
programming, strings


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Disappearing Icons - HELP! Myrlin Suse/Novell 3 08-10-2006 01:48 PM
disappearing applications vanderbult Linux - Software 4 04-24-2006 11:17 PM
how to find duplicate strings in vertical column of strings markhod Programming 7 11-02-2005 05:04 AM
Disappearing sources simcox1 Linux From Scratch 4 10-13-2005 10:01 AM
Disappearing desktop regorbro Linux - Distributions 1 03-02-2004 06:17 PM


All times are GMT -5. The time now is 10:14 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration