C Question

Soldato
Joined
19 Dec 2009
Posts
2,669
Location
Lancashire
Hi all, have a C question that's probably going to be really simple to those in the know, but this is really frustrating me at the moment as I can't figure out how to solve it.

I'm in the middle of writing a program and one of the functions gets the path of a specified file, using realpath(). I'm using the first answer to this at the moment: http://stackoverflow.com/questions/1563168/example-of-realpath-function-c-programming

If I put that code in main(), it works fine. However, when I try to use it in my get_path() function, I end up with warnings when compiling. Here is the code I am using:

Code:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

char get_path(char *filename);

int main(int argc, char **argv)
{
	char filepath = get_path(argv[1]);

	printf("%s", filepath);

	return 0;
}

/* Get the full path of the file */
char get_path(char *filename)
{
	char buf[PATH_MAX + 1];
	char *res = realpath(filename, buf);
	if (res) {
		return buf;
	} else {
		perror(filename);
		exit(EXIT_FAILURE);
	}
}

When compiling, I get the following output:

Code:
gcc filepath.c -o filepath
filepath.c: In function ‘get_path’:
filepath.c:22:3: warning: return makes integer from pointer without a cast [enabled by default]
filepath.c:22:3: warning: function returns address of local variable [enabled by default]

Could someone tell me what I'm doing wrong, what I should be doing and, more importantly, why I should be doing it? I've looked all over the place and I'm really not sure. I'm not very experienced with C and I'm learning as I go, so any help would really be appreciated. I want to understand where I'm going wrong here, because I think I have enough knowledge to write the rest of the program and figure out how to use libcurl (I'm writing a program to upload images to a popular hosting site), but I'm really stumbling with this.

Also, feel free to point and laugh and call me a noob since it's probably obvious! :p
 
Ok I see three problems.

First, your function prototype indicates that it's returning a single character object. Great if you want to return a letter, but not so good if we want to return an array of letters. So in C arrays are defined by a pointer to some area of memory allocated to hold the array of 'char' objects. So we actually want to return a pointer to an array.

Secondly, you are trying to return a locally instantiated array on the stack whatever you will return will end up unpredictable, as once the function has finished, the allocated memory in the stack for your buf array will no longer be reserved, and thus may be cleared or overwritten at any time. So your main function will have a pointer to some address that may not have what you expect in it.

Third in your main you have a char variable which will hold a maximum of one character. That should be a pointer to an array.

The reason it worked for the person in the stackoverflow case is that it was all in a main function. The troubles you have stem from the fact you're trying to use it in a function.

My advice would be to pass your filepath array as an argument to get_path and then fill it in there.
 
Your return buf; like is causing the warning about returning a local variable, when it drops out of scope it's gone, the first warning is because your return type is a char, but return buf is actually returning a char*.

You could pass a char* as a second argument to get_path and initialize it within the function, and then make its return void.
 
Code:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

void get_path(char *filename, char *buf);

int main(int argc, char **argv)
{
	char filepath[PATH_MAX + 1];
        get_path(argv[1], filepath);
	printf("%s", filepath);

	return 0;
}

/* Get the full path of the file */
void get_path(char *filename, char *buf)
{
	char *res = realpath(filename, buf);
	if (res) {
		return;
	} else {
		perror(filename);
		exit(EXIT_FAILURE);
	}
}

Couple suggestions for fixes. I've not had any experience with this realpath function but it seems that there may be more you might want to implement in the way of dealing with errors, especially wrt this res variable that gets returned.

What are you actually trying to do with this? :p maybe there's a better way.

EDIT: Also can you actually initialise directly from a function in strict old-school C? Can't remember :o
 
Last edited:
Thanks for the replies. Admittedly, my pointer knowledge is sketchy and I'm still trying to get my head round that properly (have had it explained to me, but it's not sticking - even the K&R book isn't helping there), but I see what you're saying about the other issues and it makes sense now they've been pointed out to me! >.<

Being able to see the changes you've made is quite helpful, too. In terms of what I'm doing with it, this is going to form part of a program that will upload images to a website. I basically want the user to be able to run program [filename] and have it upload, but my mess around doing it in Perl a while ago required the full path to the file, which is why I've been trying to use realpath here. I'm not sure whether or not there is a better way. I looked at using getcwd, but I can see plenty of problems that could arise if I did that. The only alternative I found so far was realpath. :/

When you say strict old-school C, are you referring to the ANSI standard?
 
Yea i mean ANSI C89. Not played with C99 much yet myself. To be honest, as far as I've heard (and i would tend to agree), K&R is most useful as a reference when you already know C. Have it on my shelf though, comes in handy every so often :D

At the end of the day, if the function you have there works then happy days. Spent the last few minutes googling and realpath appears to be implementation specific, but if it does what you need it to do then fantastic :)
 
Cheers for that. If what you say is the case about K&R, perhaps I'm not ready for it yet. I know the basics, have a grasp on basic to intermediate programming concepts etc. but more advanced features of C (pointers, the pre-processor etc.) are still fairly new to me. Are there any resources aimed more at people who are more in the beginner to intermediate range for C, but have experience of other languages? I'd say I'm fairly competent when it comes to Perl, but that's a different kettle of fish.

With regards to ANSI, I don't think so.
 
...With regards to ANSI, I don't think so.

Yea wasnt sure..if it compiles though then who am i to argue :D


Cheers for that. If what you say is the case about K&R, perhaps I'm not ready for it yet. I know the basics, have a grasp on basic to intermediate programming concepts etc. but more advanced features of C (pointers, the pre-processor etc.) are still fairly new to me. Are there any resources aimed more at people who are more in the beginner to intermediate range for C, but have experience of other languages? I'd say I'm fairly competent when it comes to Perl, but that's a different kettle of fish...

Tbh I started out with C++ and worked back to strict C89 on a uni course :( so the only real difficulty was the subtle differences in the stricter syntax.

In all honesty, if you're reading K&R, using websites like stack overflow and others online and working on your own projects though then that's fine :), probably the best way to learn any programming language. I just wouldnt expect someone to sit locked in a room for a day with K&R and come out being happy with writing in C..
 
Hehe. It doesn't compile with the -ansi flag passed to GCC, though. :p

I always feel bad for just looking around and hacking stuff together because it doesn't feel like I'm learning any of the concepts behind programming, just how to do a certain thing in a language. :o

Currently looking through some of the Stanford videos on YouTube to see if I can pick up the theory stuff as well, seems to be okay so far but some of it is also going way over my head (e.g. how a floating point number is represented in memory). With any luck I'll pick up the important bits, though :)
 
Back
Top Bottom