473,320 Members | 1,868 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Pointers and Arrays in C

I usually program in Java, so I am a bit confused about usint pointers in C.
I would really appreciate if someone can help me.

Case 1:
======

// Is this function no good? Since str is a variable created on stack,
// I am assuming it will be deallocated immedately after the function returns,
// right??
char * generateString()
{
char str[100] = "abc";
return str;
}

Case 2:
=====

// str is a pointer pointing to a literal
// Can I use str just like other char arrays?
// How are memory allocated for literals and when are they deallocated??
void main()
{
char * str;
str = "abc";
}

Case 3:
=====

// Similar to case 2 except the literal is returned from a function
// Again, can I use str for anything? When is it deleted from memory??
void main()
{
char * str;
str = generateString();
}

char * generateString()
{
return "abc";
}

Case 4:
=====

// assigning dynamically allocated array to pointer
void main()
{
char * str;
str = generateString();
...
delete str; // I have to delete str at the end, Right?
}

char * generateString()
{
char * charArray = new char[20];
strcpy(charArray, "abc");
return charArray;
}

Case 5:
=====

// str points to a char array created in a C library function
// How was this char array allocated? When will it be deallocated?
// Do I have to delete it explicitly??
void main()
{
char line[20] = "abc#def";
char * str;

str = strtok(line, "#");

delete str; // is this necessary?
// can I modify the content of the array??
}
Jul 19 '05 #1
7 1996
Terence wrote:
I usually program in Java, so I am a bit confused about usint pointers in C.
I would really appreciate if someone can help me.

Case 1:
======

// Is this function no good? Since str is a variable created on stack,
// I am assuming it will be deallocated immedately after the function returns,
// right??
You are fundamentally correct (it may or not actually be
*deallocated* but it no longer logically exists once the block in
which it is declared is exited).
char * generateString()
{
char str[100] = "abc";
return str;
}

Case 2:
=====

// str is a pointer pointing to a literal
// Can I use str just like other char arrays?
// How are memory allocated for literals and when are they deallocated??
void main()
Say it with me:
main() returns int main() returns int main() returns int
{
char * str;
str = "abc";
}

A literal exists for the life of the program. The mechanism is
irrelevant (and an issue for the implementation). It may not be mutable.
Case 3:
=====

// Similar to case 2 except the literal is returned from a function
// Again, can I use str for anything? When is it deleted from memory??
void main()
{
char * str;
str = generateString();
Yes -- but don't try to change it.
}

char * generateString()
{
return "abc";
}

Case 4:
=====

// assigning dynamically allocated array to pointer
void main()
Say it with me:
main() returns int main() returns int main() ...
{
char * str;
str = generateString();
...
delete str; // I have to delete str at the end, Right?
}

char * generateString()
{
char * charArray = new char[20];
strcpy(charArray, "abc");
return charArray;
}
Correct.

Case 5:
=====

// str points to a char array created in a C library function
// How was this char array allocated? When will it be deallocated?
// Do I have to delete it explicitly??
void main()
{
char line[20] = "abc#def";
char * str;

str = strtok(line, "#");

delete str; // is this necessary?
Not only unnecessary -- but doing so would invoke undefined
behavior, likely resulting in a crash (but only if you're lucky; the
other possibilities are considerably more frightening).
// can I modify the content of the array??
Yes you can. Be aware, however, that strtok alters what its first
argument points to -- so what `str' points to might surprise you.
Reaed whatever documentation is available at least twice before
using strtok().
}


HTH,
--ag

--
Artie Gold -- Austin, Texas
Oh, for the good old days of regular old SPAM.

Jul 19 '05 #2
In article <N6******************@twister01.bloor.is.net.cable .rogers.com>,
Terence <fi****@hotmail.com> wrote:
I usually program in Java, so I am a bit confused about usint pointers in C.
I would really appreciate if someone can help me.
If you haven't already, go read the FAQ at
http://www.parashift.com/c++-faq-lite/

This will probably answer a lot of your questions faster than waiting for
a reply on the newsgroup, though a quick look to refresh my memory didn't
find anything about a few of these (the ones about string literals).
Case 1:
======

// Is this function no good? Since str is a variable created on stack,
// I am assuming it will be deallocated immedately after the function returns,
// right??
That's correct. str goes away when generateString returns, and the
pointer to it that you're returning becomes invalid.
char * generateString()
{
char str[100] = "abc";
return str;
}
Case 2:
=====

// str is a pointer pointing to a literal
// Can I use str just like other char arrays?
Almost; you can't modify it, but otherwise, yes. (So you can treat it
exactly like you would treat any other array of const char.)
// How are memory allocated for literals and when are they deallocated??
They are allocated before the program starts and deallocated after it
ends, so any pointer you have that points at a string literal will be
valid anywhere you use it.
void main()
main always returns int in both C and C++.
(Hmm, you said you're coming from Java, didn't you? Excuse me for
a minute while I go poke my sigmonster with a pointy stick... There,
that's better.)
{
char * str;
str = "abc";
}

Case 3:
=====

// Similar to case 2 except the literal is returned from a function
// Again, can I use str for anything? When is it deleted from memory??
Yes. What you're returning is a pointer to the first element in the
array represented by the string literal; unlike the array on the stack
in case 1, this will still be there when generateString returns.
void main()
{
char * str;
str = generateString();
}

char * generateString()
{
return "abc";
}
Case 4:
=====

// assigning dynamically allocated array to pointer
This is almost correct.
Aside from the void main that I've noted elsewhere, you also have a
mismatched new/delete; memory allocated with "new type[size]" needs to
be deallocated with delete[], not plain delete.

But yes, you do have to deallocate the memory you allocated in
generateString when you're done with it. Every new needs a matching
delete.

void main()
{
char * str;
str = generateString();
...
delete str; // I have to delete str at the end, Right?
}

char * generateString()
{
char * charArray = new char[20];
strcpy(charArray, "abc");
return charArray;
}
Case 5:
=====

// str points to a char array created in a C library function
// How was this char array allocated? When will it be deallocated?
// Do I have to delete it explicitly??
Using strtok for this is a bad example, because it works on the string
you give it and doesn't create a copy for you, so in your example you
don't need to deallocate str (since it points into memory that will be
deallocated for you when the function returns) and you can modify it
(as long as you don't step outside the bounds of your 20-element array).
In fact, I don't know of any C library functions (besides the obvious
malloc and friends) that allocate memory for you, so I'm not sure your
question as asked makes sense.

If your question referred to strdup (a unixism that copies a string
into memory obtained from malloc), the answer would be that you need to
release that memory by passing the pointer you got from strdup to free()
when you're done with it.
More generally, if you're using a library function (whether it's from the
standard library or another library) that allocates resources, you need
to find out how those resources were allocated and how you're expected
to release them when you're done with them.
void main()
{
char line[20] = "abc#def";
char * str;

str = strtok(line, "#");

delete str; // is this necessary?
// can I modify the content of the array??
}

dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Did you know they sometimes have "int main" threads in
comp.lang.java.programmer? ... Perhaps we could arrange some kind of
exchange program... --Richard Heathfield in comp.lang.c
Jul 19 '05 #3
In article <bn**********@rumours.uwaterloo.ca>,
Dave Vandervies <dj******@csclub.uwaterloo.ca> wrote:
Yes. What you're returning is a pointer to the first element in the
array represented by the string literal; unlike the array on the stack
in case 1, this will still be there when generateString returns.


Before the pedants[1] start beating me over head for this, the "stack"
I'm referring to is the function-invocation stack. This is typically
implemented using a hardware stack, but anything that "looks stack-like"
at the granularity of all-the-automatic-variables-in-a-function is a
valid way of doing it.
dave

[1] CLC++ *does* have pedants, I hope? CLC would be far less interesting
(and far less informative) without them, and I assume that the same
goes for here.

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Did you know they sometimes have "int main" threads in
comp.lang.java.programmer? ... Perhaps we could arrange some kind of
exchange program... --Richard Heathfield in comp.lang.c
Jul 19 '05 #4
Terence wrote:
I usually program in Java, so I am a bit confused about usint pointers
in C.
If your question is about C, you should ask in a C newsgroup instead of
one about C++. Your questions however mostly apply to C as well as C++.
I would really appreciate if someone can help me.

Case 1:
======

// Is this function no good? Since str is a variable created on
stack,
// I am assuming it will be deallocated immedately after the function
returns,
// right??
char * generateString()
{
char str[100] = "abc";
return str;
}
The C++ standard doesn't require it to be stored on a stack. Anyway,
it's an automatic variable that is destroyed when it goes out of scope,
which happens when you return from the function. So you must not use
the returned pointer outside the function. Thus, I'd rather say that
the memory is deallocated immediately before the function returns or
exactly at the moment when it returns. The important part is just that
you cannot use it outside the function.
Case 2:
=====

// str is a pointer pointing to a literal
// Can I use str just like other char arrays?
// How are memory allocated for literals and when are they
deallocated?? void main()
{
char * str;
str = "abc";
}
A literal exists for the whole life time of the program, so you can use
a pointer to it even outside the function. You can't use it like "other
char arrays", because you may not write to it. The reason why it's
allowed to let a pointer to non-const point to it is historical (a
legacy from C).
Btw: main must return int.
Case 3:
=====

// Similar to case 2 except the literal is returned from a function
// Again, can I use str for anything? When is it deleted from
memory?? void main()
{
char * str;
str = generateString();
}

char * generateString()
{
return "abc";
}
Just as above, the literal exists as long as the program is running, so
you're free to use it anywhere, but again, you must not write to it.
Better let generateString return a const char*, so you can't by
accident write to it.
Case 4:
=====

// assigning dynamically allocated array to pointer
void main()
{
char * str;
str = generateString();
...
delete str; // I have to delete str at the end, Right?
}

char * generateString()
{
char * charArray = new char[20];
strcpy(charArray, "abc");
return charArray;
}
That's almost correct. If you use new, you need a corresponding delete.
If you use new[], you need delete[], so your last line of main would
need to be:

delete [] str;
Case 5:
=====

// str points to a char array created in a C library function
// How was this char array allocated? When will it be deallocated?
// Do I have to delete it explicitly??
void main()
{
char line[20] = "abc#def";
char * str;

str = strtok(line, "#");

delete str; // is this necessary?
// can I modify the content of the array??
}


strtok doesn't allocate any memory. It modifies the char array you gave
to it.
Generally, look into the documentation of a function. It should always
tell you whether you have to deallocate any memory from it or not.
Jul 19 '05 #5
Dave Vandervies wrote:
Yes. What you're returning is a pointer to the first element in the
array represented by the string literal; unlike the array on the stack
in case 1, this will still be there when generateString returns.
Before the pedants[1] start beating me over head for this, the "stack"
I'm referring to is the function-invocation stack. This is typically
implemented using a hardware stack, but anything that "looks
stack-like" at the granularity of all-the-automatic-variables-
in-a-function is a valid way of doing it.


Couldn't an implementation even choose to dynamically allocate the
automatic variables internally and when they go out of scope, delete
them again? Not the fastest solution, but valid AFAIK.
[1] CLC++ *does* have pedants, I hope?
I thought all the regulars are pedants, aren't they?
CLC would be far less interesting (and far less informative) without
them, and I assume that the same goes for here.


Jul 19 '05 #6
In article <bn*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote:
Dave Vandervies wrote:
Yes. What you're returning is a pointer to the first element in the
array represented by the string literal; unlike the array on the stack
in case 1, this will still be there when generateString returns.


Before the pedants[1] start beating me over head for this, the "stack"
I'm referring to is the function-invocation stack. This is typically
implemented using a hardware stack, but anything that "looks
stack-like" at the granularity of all-the-automatic-variables-
in-a-function is a valid way of doing it.


Couldn't an implementation even choose to dynamically allocate the
automatic variables internally and when they go out of scope, delete
them again? Not the fastest solution, but valid AFAIK.


Yep, it would be valid, but you'd still end up with something that looks
stack-like; the first function invoked (or, more precisely, the first
scope entered) would be the bottom of the stack, and the most recent one
would be the top. When you enter a scope, you create a new invocation
record and push it onto the stack; when you leave, you pop and discard
the record at the top, and return to the scope represented by the next
record down.

[1] CLC++ *does* have pedants, I hope?


I thought all the regulars are pedants, aren't they?


I would be worried if they weren't.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Did you know they sometimes have "int main" threads in
comp.lang.java.programmer? ... Perhaps we could arrange some kind of
exchange program... --Richard Heathfield in comp.lang.c
Jul 19 '05 #7
< snipped questions about pointer and C-style string handling>

Other have answer your questions already. But since you are asking the
questions in comp.lang.c++ and you are new to C++ (I presume), you might
be interested in the std::string class. The std::string class makes
string handling much easier and less error prone compared to C style
strings; no need to worry about pointers, life time issues, allocating
sufficient memory...etc. Also string manipulation is much more
convenient with this class:

#include <iostream>
#include <string>
using namespace std;

string generateString(string name)
{
string str = "Hello " + name + "!";
return str;
}

int main()
{
cout << "Your name ? ";
string name;
getline(cin, name);
string msg = generateString(name);
cout << msg << endl;
return 0;
}

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 19 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: Thomas Matthews | last post by:
Hi, Given a structure of pointers: struct Example_Struct { unsigned char * ptr_buffer; unsigned int * ptr_numbers; }; And a function that will accept the structure:
11
by: Linny | last post by:
Hi, I need some help in declaring an array of pointers to array of a certain fixed size. I want the pointers to point to arrays of fixed size only (should not work for variable sized arrays of the...
79
by: Me | last post by:
Just a question/observation out of frustration. I read in depth the book by Peter Van Der Linden entitled "Expert C Programming" (Deep C Secrets). In particular the chapters entitled: 4: The...
6
by: Carl-Olof Almbladh | last post by:
Already in the 1st edition of the "White book", Kerigham and Ritchie states the "C is a general purpose language". However, without what is usually called "assumed size arrays" and built-in...
5
by: Paminu | last post by:
Why make an array of pointers to structs, when it is possible to just make an array of structs? I have this struct: struct test { int a; int b;
36
by: raphfrk | last post by:
I have the following code: char buf; printf("%lp\n", buf); printf("%lp\n", &buf); printf("%lp\n", buf); printf("%lp\n", buf); printf("%d\n", buf-buf);
14
by: code break | last post by:
what is the difference in this pointers decalarition ? int *ptr; and int (*ptr);
6
by: joelperr | last post by:
Hello, I am attempting to separate a two dimensional array into two one-dimensional arrays through a function. The goal of this is that, from the rest of the program, a data file consisting of...
8
by: Piotrek | last post by:
Hi, Like almost all of beginners I have problem understanding pointers. Please, look at this piece of code, and please explain me why myswap function doesn't work as it's supposed to do, whereas...
0
by: David Thompson | last post by:
On Wed, 09 Apr 2008 12:34:43 +0500, arnuld <arnVuld@ippiVmail.com> wrote: I think you've got the idea, but: - I would be careful about using 'equal'. Pointers and arrays are different things,...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.