LinuxQuestions.org
Help answer threads with 0 replies.
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 11-03-2005, 08:39 PM   #1
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Rep: Reputation: 30
char * question


I am wondering what happens in the followings situation:

char * test = "hi";
test = "how are you";

Now, the way I understand it, the first line creates a block of memory that contains "h" "i" and "\0". When I have the pointer point to a new string of characters,

if
1) a new block of memory is allocated, what happens to the old block of memory?

if
2) the memory is overwritten, then doesn't this create the possibility that the code unintentionally overwrites memory that shouldn't be touched?

When I really think about it, char *test and char test[] really are interchangeable, right? So the second should apply, I believe.

Just looking for confirmation.
Thanks.
 
Old 11-03-2005, 08:59 PM   #2
lowpro2k3
Member
 
Registered: Oct 2003
Location: Canada
Distribution: Slackware
Posts: 340

Rep: Reputation: 30
Since those strings are set at compile time, they're stored in memory (i think in a const area, but not sure). When you say 'x = "hello world";', you're just shifting the x pointer to another string which I cant for the life of me remember the name of.

char x[] and char *x are fairly interchangable, yes
 
Old 11-03-2005, 09:06 PM   #3
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Original Poster
Rep: Reputation: 30
Well if I have a user input a string value:

cin >> test;

Will this cause memory to be overwritten (that shouldn't be?). I have to assume that it would overwrite memory in a bad way.

Thanks for your time.
 
Old 11-03-2005, 09:08 PM   #4
lowpro2k3
Member
 
Registered: Oct 2003
Location: Canada
Distribution: Slackware
Posts: 340

Rep: Reputation: 30
I was gonna post about that too

I forget exactly where static strings are stored in memory, but I think they're flagged as read-only. So you would pass your pointer to char to cin, which would try and write to this illegal memory. Off the top of my head I'm guessing segfault...

Haven't tested this lately to be sure
 
Old 11-03-2005, 09:49 PM   #5
nonzero
Member
 
Registered: Feb 2005
Distribution: Debian FC4 LFS Slackware
Posts: 174

Rep: Reputation: 31
I am just a hobbyist programmer but there appear to be some basic flaws in your thinking in the above code fragment.

First, you can't assign a value of 'hi' to the pointer 'test' without first assigning it an address of something (the variable 'q' in my example).

Second, the compiler (at least gcc) will allow (but complain), a multicharacter constant in the example below but the output is not what you expect and you are courting crashes with anything more complicated.

#include "stdio.h"

main()
{
char *test, q;
test = &q; /* get q's address */
*test = 'hi'; /* assign q a value using a pointer */
printf("q's value is %c", q); /* simple printf statement to illustrate */
)

Save the above fragment as test.c, run 'gcc test.c' then execute the resulting a.out. Then edit the test.c file to take out the i in 'hi' and see what happens. Hint: Look at the warnings from the compiler as it builds the a.out. Also fiddle with the single quotes I replaced your double quotes with in the assignment statement and see what happens.

nz

EDIT put some whitespace in between the end of my statements and the first comment forward slash character if you cut and past the fragment. Still trying to get used to the darn LQ editor

Last edited by nonzero; 11-03-2005 at 09:54 PM.
 
Old 11-03-2005, 10:22 PM   #6
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

1. Yes, the string constants are allocated at compile time, in a (typically read-only) area called the "TEXT" section.

2. Kroenecker's original post:
Code:
char * test = "hi";
test = "how are you";
was perfectly correct. He declared a pointer ("test"), he assigned it to something (the 3-byte constant "hi\0", and then assigned it to something else (the 12-byte constant "how are you\0". All well and good.

3. For whatever it's worth, the following might explain a bit better:
Code:
/*
 * 1. gcc compile:
 *    gcc -g -o xyz xyz.c
 *
 * 2. Debug session:
 *  gdb command:  gdb response:
 *  -----------   ------------
 *  (gdb) b main  Breakpoint 1 at 0x80483a8: file x.c, line 5.
 *  (gdb) r       Starting program: /tmp/x
 *  (gdb) n       6         test = "hi";
 *  (gdb) p       test $2 = 0x0
 *  (gdb) n       8         test = "how are you";
 *  (gdb) p test  $3 = 0x80484e8 "hi"
 *  (gdb) n       10        return 0;
 *  (gdb) p test  $4 = 0x80484eb "how are you"
 */
#include <stdio.h>

main (int argc, char *argv[])
{
                           /* #/Bytes     Where         When         */
                           /* Allocated   Allocated     Allocated    */
                           /* ---------   ---------     ---------    */
  char * test = 0;         /* 4 bytes     STACK         RUNTIME      */
  test = "hi";             /* 3 bytes     TEXT SECTION  COMPILE TIME */
  test = "how are you";    /* 12 bytes    TEXT SECTION  COMPILE TIME */
  return 0;
}
4. You can find out more about the TEXT, DATA, CODE and BSS sections here:
http://www.gnu.org/software/binutils...s_4.html#SEC41

'Hope that helps .. PSM
 
Old 11-04-2005, 12:29 AM   #7
gxf
LQ Newbie
 
Registered: Oct 2005
Posts: 10

Rep: Reputation: 0
int a = 0; //global init
char *p1; //global no init
main()
{
int b; //stack
char s[] = "abc";//allocated 4 bytes in stack , writable
char *p2; //stack
char *p3 = "123456"; //123456\0 in constant area ,cann't change .p3 in stack ,usually it contain 4 bytes .
static int c =0; global£¨static£©init
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//the above 10 and 20 bytes are allocated in heap,you want to free.
strcpy(p1, "123456");
}
 
Old 11-04-2005, 12:48 AM   #8
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Original Poster
Rep: Reputation: 30
Very much appreciated. That is the first time that I have been able to use gdb. Thanks so much.

I have another question now about std::cin.getline(char*, int n);

If a user inputs a string that is longer than n, it seems that all other getline calls go without putting any value into the buffer be it a new buffer or the old one.

I used gdb to step through, but it wasn't apparent what was going wrong.

Could you give me a hint?

char buffer[10];
std::cin.getline(buffer, 10);
std::cout << buffer << std::endl;
char buffer2[10];
std::cin.getline(buffer2, 10);
std::cout << buffer2 << std::endl;

so is newline creating a problem? And if so, is there a way to "flush" out the newline so that I can get to new user output?
 
Old 11-04-2005, 01:41 AM   #9
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Original Poster
Rep: Reputation: 30
Ive tried using sync() and ignore(), but neither seem to work.

Any ideas?

Again, if the user enters something that is longer than the buffer, is there a way get this code to work?
 
Old 11-04-2005, 02:23 AM   #10
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
why do people make their buffers so small?
 
Old 11-04-2005, 03:24 AM   #11
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Original Poster
Rep: Reputation: 30
Oh I'm just curious about how everything works. I wouldn't necessarily write a program with really small buffers.
 
Old 11-04-2005, 03:31 AM   #12
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
excellent!
that is the correct answer

reading user input is always a trciky business.

post a complete bit of code so as we can compile and try what you mean.
(I don't use C++ only C, too much typing! )
 
Old 11-04-2005, 03:47 AM   #13
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Original Poster
Rep: Reputation: 30
Well after googling about, I found out about a few helpful stream functions:

stream.fail() and stream.clear()

Basically if getline receives a stream that is too long for the buffer, the fail flag will be set. This flag can be tested by using fail(). So in my case since I'm using cin:

std::cin.getline(buffer, 10);
std:: out << buffer << std::endl;
if( std::cin.fail() )
{
std::cout << "Too much user input... " << std::endl;
std::cin.clear(); // This clears the flag
}
//Now the next getline call will resume where the previous one had
//cut off.
std::cin.getline(second_buffer, 10);
std::cout << second_buffer << std::endl;

In this way you could use cin.fail() in a do while statement to ensure that the user inputs a string that is small enough to fit into your buffer.

Thanks all. I'm sure I will be coming up with more questions in the coming weeks
 
Old 11-04-2005, 03:51 AM   #14
Kroenecker
Member
 
Registered: May 2003
Location: The States
Distribution: Gentoo
Posts: 245

Original Poster
Rep: Reputation: 30
By the way if anyone can suggest detailed reading about memory allocation at compile time/run time for c/c++, I would appreciate it.
 
Old 11-04-2005, 04:10 AM   #15
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
I used to know all about memory allocation
but, er... no, where was I?

it's simple, allocate it. check return value. free it once when finished.
even better, avoid using it at all costs.
 
  


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
Question about writing (char)0 to a pipe. karlan Programming 1 06-05-2005 04:23 PM
C pointers confusion - char ** = char [][] ?? saravkrish Programming 12 12-02-2004 10:06 AM
C Problem---convert char to char* totti10 Programming 11 11-06-2004 11:32 AM
invalid conversion from `char' to `const char* bru Programming 6 05-09-2004 03:07 PM
convert from char* to unsigned char* D J Linux - Software 2 02-20-2004 04:09 AM

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

All times are GMT -5. The time now is 11:01 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