LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
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 10-23-2010, 08:20 PM   #1
MrCode
Member
 
Registered: Aug 2009
Location: Oregon, USA
Distribution: Arch
Posts: 864
Blog Entries: 31

Rep: Reputation: 148Reputation: 148
Unhappy 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. :-(
 
Old 10-23-2010, 08:35 PM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by MrCode View Post
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.
How about reading

man 3 malloc

?
 
Old 10-23-2010, 08:40 PM   #3
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
And

man 3 strcpy
man 3 strlen
.
 
Old 10-23-2010, 08:54 PM   #4
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Rep: Reputation: 139Reputation: 139
Quote:
Originally Posted by MrCode View Post
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
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.
 
Old 10-23-2010, 09:04 PM   #5
MrCode
Member
 
Registered: Aug 2009
Location: Oregon, USA
Distribution: Arch
Posts: 864

Original Poster
Blog Entries: 31

Rep: Reputation: 148Reputation: 148
Thanks JohnGraham for the tips. I got it working.

Code:
$ ./reverser "This is a test."
.tset a si sihT
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.

Last edited by MrCode; 10-23-2010 at 09:06 PM.
 
Old 10-23-2010, 09:59 PM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by MrCode View Post
...
I got rid of the "implicit declarations" warnings by including the appropriate headers (got that tip from a quick Google search)
...
You doubt manpages tell the same ?
 
Old 10-23-2010, 10:13 PM   #7
MrCode
Member
 
Registered: Aug 2009
Location: Oregon, USA
Distribution: Arch
Posts: 864

Original Poster
Blog Entries: 31

Rep: Reputation: 148Reputation: 148
Quote:
You doubt manpages tell the same ?
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.
 
Old 10-23-2010, 10:27 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by MrCode View Post
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.
 
Old 10-24-2010, 12:03 AM   #9
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
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.
 
Old 10-24-2010, 12:19 AM   #10
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by theNbomr View Post
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>
 
Old 10-24-2010, 12:43 AM   #11
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Suggested alternative:
Code:
#include <stdio.h>
#include <string.h>
#include <malloc.h>

int main(int argc,char** argv)
{
  if (argc != 2)
  {
    printf ("USAGE: Enter a string\n");
    return 1;
  }

  int ilen = strlen (argv[1]);
  char* str = (char *)malloc (ilen + 1);
  strcpy(str, argv[1]);
  ...
PS:
I, too, agree with Sergei

PPS:
You could also lose the "malloc()" and substitute "strdup()"...

Last edited by paulsm4; 10-24-2010 at 12:45 AM.
 
Old 10-24-2010, 01:34 AM   #12
MrCode
Member
 
Registered: Aug 2009
Location: Oregon, USA
Distribution: Arch
Posts: 864

Original Poster
Blog Entries: 31

Rep: Reputation: 148Reputation: 148
@theNbomr

Quote:
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.

Last edited by MrCode; 10-24-2010 at 01:36 AM.
 
Old 10-24-2010, 10:21 AM   #13
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
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.

--- rod.
 
  


Reply



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
Linux memory management: Real memory or Cached buffers? gubbu Linux - Server 2 10-01-2010 01:58 AM
Need help coming up with a package management system ReyJavikVI Linux From Scratch 6 06-15-2009 03:04 PM
Searching memory for pointers KareemSedki Linux - Kernel 8 11-02-2007 06:46 AM
Of pointers - seg faults, memory leaks and assorted troubles vharishankar Programming 3 08-03-2006 08:18 AM
pointers and dynamic memory allocation deveraux83 Programming 2 01-24-2004 10:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:51 AM.

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
Open Source Consulting | Domain Registration