LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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 07-21-2010, 07:26 PM   #1
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Rep: Reputation: 133Reputation: 133
puts(rubbish)...


Yes, that's what it does for some reason. The code below prints garbage if I use puts() but it is fine if I use printf() instead (see sample of output at the bottom of this post).

Any idea what could be causing this? The odd thing is that the mess always starts after exactly eight properly printed characters. That sort of regularity can't be a coincidence, can it? It almost looks like an encoding issue (I'm using UTF-8) but if it really is, then I don't understand why the printf() is unaffected.

Code:
#include <stdio.h>
#include <string.h>

const char *nChars (const char *, int);

int main (int argc, char * argv[]){
    
    char * name ="Count Dracula++";    
    int len = strlen(name);

    if (argv[1] == 0)
        argv[1]="printf";
    printf("--->%d characters\n", len);        
    
    if (argc >= 2 && !strcmp(argv[1], "puts"))        
        for (int i = 1; i <= len; i++)
            puts(nChars(name, i));
    else
        for (int i = 1; i <= len; i++)    
            printf("%s\n", nChars(name, i));

    return 0;

}

const char * nChars (const char * strptr, int n){ //returns the next n characters of input

    char * ptr;
    char nChars[n+1];
    int slen = strlen(strptr);

    if (slen < n){                 // if the string is shorter than n chars, return it unmodified
        printf ("String too short. Returning %d.\n", slen);
        return strptr;
    } else {
        ptr = nChars;        
        for (int i = 0; i < n; i++)
            ptr[i]=strptr[i];
        ptr[n]='\0';             //append null character            
        return ptr;
    }
}
output of "nChars":
Quote:
C
Co
Cou
Coun
Count
Count
Count D
Count Dr
Count Dra
Count Drac
Count Dracu
Count Dracul
Count Dracula
Count Dracula+
Count Dracula++
output of "nChars puts":

Code:

Co
Cou
Coun
Count
Count 
Count D
Count Dr
Count Dr�
Count Dr�
Count Dr��
Count Dr���1
Count Dr���1
Count Dr���1�
Count Dr���1�
 
Old 07-21-2010, 07:35 PM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by jay73 View Post
... Any idea what could be causing this? ...
What command line did you use to compile ?
 
Old 07-21-2010, 07:41 PM   #3
YetAnotherDave
Member
 
Registered: Feb 2005
Posts: 95

Rep: Reputation: 17
It looks to me like nChars is returning a pointer ( ptr ) to stack memory ( the nChars[n+1] char array) . This might not actually be the cause of the symptom you see but it's an "all bets are off" kind of problem. Your program will behave unpredictably until you fix it.
 
Old 07-21-2010, 07:45 PM   #4
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by jay73 View Post
...
Code:
#include <stdio.h>
#include <string.h>

const char *nChars (const char *, int);

int main (int argc, char * argv[]){
    
    char * name ="Count Dracula++";    
    int len = strlen(name);

    if (argv[1] == 0)
        argv[1]="printf";
    printf("--->%d characters\n", len);        
    
    if (argc >= 2 && !strcmp(argv[1], "puts"))        
        for (int i = 1; i <= len; i++)
            puts(nChars(name, i));
    else
        for (int i = 1; i <= len; i++)    
            printf("%s\n", nChars(name, i));

    return 0;

}

const char * nChars (const char * strptr, int n){ //returns the next n characters of input

    char * ptr;
    char nChars[n+1];
    int slen = strlen(strptr);

    if (slen < n){                 // if the string is shorter than n chars, return it unmodified
        printf ("String too short. Returning %d.\n", slen);
        return strptr;
    } else {
        ptr = nChars;        
        for (int i = 0; i < n; i++)
            ptr[i]=strptr[i];
        ptr[n]='\0';             //append null character            
        return ptr;
    }
}
....
Why/what for do you have the line in red ?
 
Old 07-21-2010, 07:45 PM   #5
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Original Poster
Rep: Reputation: 133Reputation: 133
colorgcc -Wall -std=c99 nChars.c

I've tried plain "gcc nChars.c" but that doesn't make any difference.
 
Old 07-21-2010, 07:48 PM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by YetAnotherDave View Post
It looks to me like nChars is returning a pointer ( ptr ) to stack memory ( the nChars[n+1] char array) . This might not actually be the cause of the symptom you see but it's an "all bets are off" kind of problem. Your program will behave unpredictably until you fix it.
Yep. A pointer to heap allocated entity should have been used instead.
 
Old 07-21-2010, 07:53 PM   #7
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Original Poster
Rep: Reputation: 133Reputation: 133
Quote:
Why/what for do you have the line in red ?
I do not want to modify the original array so I create a new array (nChars) to copy the parts that I need. The ptr is a pointer to that new array. I guess I could return the array instead of the pointer that doesn't help.
 
Old 07-21-2010, 07:58 PM   #8
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Original Poster
Rep: Reputation: 133Reputation: 133
So you mean I'll need to use malloc? I'm vaguely aware of the concept since I dabbled some in C++ a year or two ago but I have a chapter or two to go in my C manual before I reach that part. Well, I'll put it aside for now and give it another try in another few days.

Last edited by jay73; 07-21-2010 at 07:59 PM.
 
Old 07-21-2010, 08:07 PM   #9
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by jay73 View Post
So you mean I'll need to use malloc? I'm vaguely aware of the concept since I dabbled some in C++ a year or two ago but I have a chapter or two to go in my C manual before I reach that part. Well, I'll put it aside for now and give it another try in another few days.
Stack variable seize existence when the scope housing them is left. Period.

If you do not want to use 'malloc', allocate the buffer pointer to which you want to return in the calling scope, pass the buffer as argument and return nothing, i.e. implement a void function.

Last edited by Sergei Steshenko; 07-21-2010 at 08:31 PM.
 
Old 07-21-2010, 08:27 PM   #10
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Original Poster
Rep: Reputation: 133Reputation: 133
Quote:
If you do not want to use 'malloc', allocate the buffer pointer to which you want to return in thew calling scope, pass the buffer as argument and return nothing, i.e. implement a void function.
Good tips. Thanks!
 
  


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
/boot partition full of rubbish? timnp Linux - Distributions 6 12-12-2008 02:46 PM
Canon are rubbish james.farrow Linux - Hardware 25 10-24-2006 04:27 AM
Rubbish Resolution - only viewable on 1024x768 Rikular Linux - Newbie 3 11-23-2004 02:13 PM
Check out this MS rubbish BajaNick General 2 06-27-2004 01:53 PM
FTP is rubbish uveraser General 8 06-12-2004 09:44 PM

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

All times are GMT -5. The time now is 06:22 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
Open Source Consulting | Domain Registration