[SOLVED] Having *serious* troubles coming back to grips with memory management/pointers
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Having *serious* troubles coming back to grips with memory management/pointers
Yeah, yeah, this is probably going to seem like a "homework question", but I'm doing this out of interest, not for a school assignment.
I'm just trying to write a small C program that takes a string as an argument and reverses it (manually, without strrev()). This, of course, requires knowledge of how to manage memory and manipulate pointers:
Code:
#include <stdio.h>
int main(int argc,char** argv)
{
char* str;
str = malloc(100);
strcpy(str,*(argv+1));
int i = strlen(str);
while (i > 0)
{
printf("%s",str[i]);
i--;
}
free(str);
return 0;
}
Here are the compiler warnings:
Code:
reverser.c: In function ‘main’:
reverser.c:7:2: warning: implicit declaration of function ‘malloc’
reverser.c:7:8: warning: incompatible implicit declaration of built-in function ‘malloc’
reverser.c:9:2: warning: implicit declaration of function ‘strcpy’
reverser.c:9:2: warning: incompatible implicit declaration of built-in function ‘strcpy’
reverser.c:11:2: warning: implicit declaration of function ‘strlen’
reverser.c:11:10: warning: incompatible implicit declaration of built-in function ‘strlen’
reverser.c:15:3: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
reverser.c:19:2: warning: implicit declaration of function ‘free’
reverser.c:19:2: warning: incompatible implicit declaration of built-in function ‘free
The program just segfaults whenever I run it (it doesn't matter whether it has args or not) :
Code:
$ ./reverser reverse
Segmentation fault
I've highlighted the suspect warning which I think is the culprit, but I'm not sure. What I want to know is why it thinks str[i] are ints. From what I can tell, they should be chars...
But, seeing as how apparently I'm dumb and don't know how to handle pointers, there's probably a lot more to the issue than that.
I've tried other solutions that involved a "cpy" variable and experiments with memcpy() and strcat(), but of course both of those want pointers for their second param (as opposed to a single variable from an array, which is what I need to iterate through the argument string and print them back in reverse). I thought that using printf() would be pretty straightforward, but apparently that's not the case.
Again, I apologize if this seems to be an über-n00bish question (the program is 16 lines long, for crying out loud! Of which only about half are actually translated to instructions ), but it's been a while since I last wrote a C program of any real length, and I'm trying to get back up to speed.
Last edited by MrCode; 10-23-2010 at 08:30 PM.
Reason: changed code/warnings...it might be a little more sane now, but it still doesn't work. :-(
Yeah, yeah, this is probably going to seem like a "homework question", but I'm doing this out of interest, not for a school assignment.
I'm just trying to write a small C program that takes a string as an argument and reverses it (manually, without strrev()). This, of course, requires knowledge of how to manage memory and manipulate pointers:
Code:
#include <stdio.h>
int main(int argc,char** argv)
{
char* str;
str = malloc(100);
strcpy(str,*(argv+1));
int i = strlen(str);
while (i > 0)
{
printf("%s",str[i]);
i--;
}
free(str);
return 0;
}
Here are the compiler warnings:
Code:
reverser.c: In function ‘main’:
reverser.c:7:2: warning: implicit declaration of function ‘malloc’
reverser.c:7:8: warning: incompatible implicit declaration of built-in function ‘malloc’
reverser.c:9:2: warning: implicit declaration of function ‘strcpy’
reverser.c:9:2: warning: incompatible implicit declaration of built-in function ‘strcpy’
reverser.c:11:2: warning: implicit declaration of function ‘strlen’
reverser.c:11:10: warning: incompatible implicit declaration of built-in function ‘strlen’
reverser.c:15:3: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
reverser.c:19:2: warning: implicit declaration of function ‘free’
reverser.c:19:2: warning: incompatible implicit declaration of built-in function ‘free
The program just segfaults whenever I run it (it doesn't matter whether it has args or not) :
Code:
$ ./reverser reverse
Segmentation fault
I've highlighted the suspect warning which I think is the culprit, but I'm not sure. What I want to know is why it thinks str[i] are ints. From what I can tell, they should be chars...
But, seeing as how apparently I'm dumb and don't know how to handle pointers, there's probably a lot more to the issue than that.
I've tried other solutions that involved a "cpy" variable and experiments with memcpy() and strcat(), but of course both of those want pointers for their second param (as opposed to a single variable from an array, which is what I need to iterate through the argument string and print them back in reverse). I thought that using printf() would be pretty straightforward, but apparently that's not the case.
Again, I apologize if this seems to be an über-n00bish question (the program is 16 lines long, for crying out loud! Of which only about half are actually translated to instructions ), but it's been a while since I last wrote a C program of any real length, and I'm trying to get back up to speed.
reverser.c: In function ‘main’:
reverser.c:7:2: warning: implicit declaration of function ‘malloc’
reverser.c:7:8: warning: incompatible implicit declaration of built-in function ‘malloc’
reverser.c:9:2: warning: implicit declaration of function ‘strcpy’
reverser.c:9:2: warning: incompatible implicit declaration of built-in function ‘strcpy’
reverser.c:11:2: warning: implicit declaration of function ‘strlen’
reverser.c:11:10: warning: incompatible implicit declaration of built-in function ‘strlen’
reverser.c:15:3: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
reverser.c:19:2: warning: implicit declaration of function ‘free’
reverser.c:19:2: warning: incompatible implicit declaration of built-in function ‘free
I've highlighted the suspect warning which I think is the culprit
All warnings are always culprits. Always make sure your code compiles without any warnings. Especially when said code isn't behaving the way you want it to. Preferably, you should use the -Werror compiler flag in addition to -Wall and -Wextra. They'll save you far more headaches than they cause you.
Quote:
What I want to know is why it thinks str[i] are ints. From what I can tell, they should be chars...
str is a char*, which means that str[0] is a char, which is an integral type. However, all integral arguments to printf get cast up to an int if they're any shorter than that. Either way, you probably want to use %c instead of %s to print a character.
Last edited by JohnGraham; 10-23-2010 at 09:02 PM.
I got rid of the "implicit declarations" warnings by including the appropriate headers (got that tip from a quick Google search), and changing the %s to %c in the format string got rid of the cast warning. Granted, it still segfaults when there are no arguments provided to it, but that can be fixed with a simple argc check.
The revised code:
Code:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main(int argc,char** argv)
{
char* str;
str = malloc(100);
strcpy(str,*(argv+1));
int i = strlen(str);
while (i >= 0)
{
printf("%c",str[i]);
i--;
}
printf("\n");
free(str);
return 0;
}
Sorry for wasting people's time on this...I know I should know better.
It's not that I "doubt the man pages could have told the same thing", it's that not everyone goes straight to the man pages...the "RTFM" attitude is rather unappreciated.
I already apologized for seeming dumb, and here you are telling me off anyway.
It's not that I "doubt the man pages could have told the same thing", it's that not everyone goes straight to the man pages...the "RTFM" attitude is rather unappreciated.
I already apologized for seeming dumb, and here you are telling me off anyway.
Unfortunately. The SOP (regardless of language) should be: you're gonna use a function, read devoted to it manpage first.
Startlingly, I have to agree with Sergei on this one. Man pages are generally poor substitutes for tutorial information for learners. However, the ease of access and conciseness of man pages for C language functions is tough to beat. Every standard C library function is present, often with a short example, and all the information needed to use the function is also there (well, almost always). It is a very useful resource and I recommend it to all programmers. It is too bad the whole language couldn't be presented so well.
Startlingly, I have to agree with Sergei on this one. Man pages are generally poor substitutes for tutorial information for learners. However, the ease of access and conciseness of man pages for C language functions is tough to beat. Every standard C library function is present, often with a short example, and all the information needed to use the function is also there (well, almost always). It is a very useful resource and I recommend it to all programmers. It is too bad the whole language couldn't be presented so well.
--- rod.
In this particular case the first burning issue was lack of '#include ...' statements, and manpages typically give this info at the very top.
I.e. you had really little room (like 9 lines) to disagree with me:
Code:
1 STRLEN(3) Linux Programmer's Manual STRLEN
1 (3)
2
3
4
5 NAME
6 strlen - calculate the length of a string
7
8 SYNOPSIS
9 #include <string.h>
Man pages are generally poor substitutes for tutorial information for learners. However, the ease of access and conciseness of man pages for C language functions is tough to beat.
I guess this is the point I was trying to get across to Sergei...I'm trying to get back to speed with C after some time of letting my skills rust (been going through existential crap lately...it put a dent in my programming interest ), so reading the man pages on the stdlib functions usually isn't the first thing that comes to my mind; I'm more apt to go for a more beginner-friendly resource on the internet first.
@paulsm4
I already added some argument-checking logic of my own, but thanks for the suggestion about getting the length of the argument string and using that as the amount of memory for malloc() to allocate, as opposed to allocating a fixed block of 100 bytes.
Reading the man pages on C functions with which you are not fully acquainted ought to be the first thing that comes to mind. It is the easiest and fastest way to get the details on how to use a function, and chances are good that it will be more accurate than a beginners tutorial. Really.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.