Hello
I need to populate an array of char arrays at run-time. A very
simplifed version of the code is below.
char ** list should contain cnt char arrays. The values of char ** list
are set by the function foo(). A pointer to char ** list is passed to
foo() as an argument.
The problem is that when foo() returns, char ** list contains rubbish
and does not always contain cnt char arrays. Can anyone tell me what
I'm doing wrong? Note that I don't want to use the vector or string for
efficiency. Note that the code that get the time has nothing to do with
the real programme. It's just a simplification for the purpose of this
posting.
(I have noticed that if the values are constant char arrays there is no
problem)
//************************************************** *******************************
#include <iostream.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
void foo(char *** array, int cnt){
char buf[256];
for(int i=0; i<cnt; i++){
long t = time(NULL); // just for demonstration
itoa(t, buf, 10);
(*array)[i] = buf;
cout << i << " " << (*array)[i] << '\n';
}
}
int main(int argc, char ** argv){
int cnt = 10;
char ** list = new char*[10];
foo(&list, cnt);
for(int i=0; i<cnt; i++){
cout << i << " " << list[i] << "\n";
}
delete [] list;
return 0;
}
//************************************************** *******************************
Thanks!!!!! 9 7582 ro*************@telefonica.net writes:
>void foo(char *** array, int cnt){
> char buf[256];
This fixes the value of buf for the duration of the function, so
> (*array)[i] = buf;
will set all the elements to the same value - the value of buf.
Also, buf is a local variable, so when foo ends, the space used by buf can be recycled.
The short answer to your question is to reconsider using containers. ro*************@telefonica.net wrote:
Hello
void foo(char *** array, int cnt){
char buf[256];
for(int i=0; i<cnt; i++){
long t = time(NULL); // just for demonstration
itoa(t, buf, 10);
(*array)[i] = buf;
cout << i << " " << (*array)[i] << '\n';
}
}
For starters, you're assigning the same local buffer 'buf' multiple
times, then that's going out of scope at the end of the function.
No offence mate, but you're clearly struggling juggling three levels of
indirection; you're going to be a lot better off using std::vector and
std::string. They are designed precisely to allow programmers to avoid
these sorts of gymnastics and pitfalls. Your concerns about
"performance" are misplaced, get the thing working in a clear and
understandable way and then worry about tweaking it for performance
*if* you need to. Which you won't. ro*************@telefonica.net wrote:
Hello
I need to populate an array of char arrays at run-time. A very
simplifed version of the code is below.
char ** list should contain cnt char arrays. The values of char ** list
are set by the function foo(). A pointer to char ** list is passed to
foo() as an argument.
The problem is that when foo() returns, char ** list contains rubbish
and does not always contain cnt char arrays. Can anyone tell me what
I'm doing wrong? Note that I don't want to use the vector or string for
efficiency. Note that the code that get the time has nothing to do with
the real programme. It's just a simplification for the purpose of this
posting.
Why not just use std::vector<std::stringand save yourself a lot of
trouble?
--
Ian Collins.
Tim Love wrote:
ro*************@telefonica.net writes:
void foo(char *** array, int cnt){
char buf[256];
This fixes the value of buf for the duration of the function, so
(*array)[i] = buf;
will set all the elements to the same value - the value of buf.
Also, buf is a local variable, so when foo ends, the space used by buf can be recycled.
The short answer to your question is to reconsider using containers.
Thanks, Tim.
I might be wrong but I'm using a pointer to char ** list and assigning
the value of buf. char ** list's values should persist after foo()
returns. Isn't that right? Thanks!!!
Rob ro*************@telefonica.net writes:
>Thanks, Tim. I might be wrong but I'm using a pointer to char ** list and assigning the value of buf. char ** list's values should persist after foo() returns. Isn't that right?
But what persists is just a pointer. It's pointing to memory that's being
rewritten then freed, so it's not a useful pointer. http://burks.bton.ac.uk/burks/langua...t/pointers.htm may help,
but vectors+strings are a safer bet. ro*************@telefonica.net skrev:
Tim Love wrote:
>ro*************@telefonica.net writes:
>>void foo(char *** array, int cnt){ char buf[256];
This fixes the value of buf for the duration of the function, so
>> (*array)[i] = buf;
will set all the elements to the same value - the value of buf.
Also, buf is a local variable, so when foo ends, the space used by buf can be recycled.
The short answer to your question is to reconsider using containers.
Thanks, Tim.
I might be wrong but I'm using a pointer to char ** list and assigning
the value of buf. char ** list's values should persist after foo()
returns. Isn't that right? Thanks!!!
You're assigning the address of 'buf' to each pointer, and 'buf' only
exists within the scope of 'foo()', not outside in 'main()'. The address
points to some location on the stack, which is recycled and overwritten
by subsequent stack operations, like the following call to
std::basic_ostream::operator<<(...).
You need to allocate the buffer with 'new' if you want it to persist,
or dismiss any thoughts of efficiency and do as others have replied,
skip deep indirection and use the provided framework of containers.
For example:
#include <sstream>
#include <vector>
#include <string>
#include <ctime>
#include <ostream>
#include <algorithms>
void foo(std::vector<std::string&v, unsigned cnt) {
std::ostringstream strm;
for(unsigned i = 0; i < cnt; ++i) {
strm << std::time(0);
v.push_back(strm.str());
strm.str("");
}
}
int main(int argc, char* argv[])
{
std::vector<std::stringv;
foo(v,10);
std::copy(v.begin(),
v.end(),
std::ostream_iterator<std::string>(std::cout,"\n") );
return 0;
}
--
TB @ SWEDEN
TB wrote:
>
You're assigning the address of 'buf' to each pointer, and 'buf' only
exists within the scope of 'foo()', not outside in 'main()'. The address
points to some location on the stack, which is recycled and overwritten
by subsequent stack operations, like the following call to
std::basic_ostream::operator<<(...).
You need to allocate the buffer with 'new' if you want it to persist,
or dismiss any thoughts of efficiency and do as others have replied,
skip deep indirection and use the provided framework of containers.
TB @ SWEDEN
Thanks to you and others who have got back to me. I'll take this
advice; but I'm still curious as to the following:
Essentially: is it possible to manipulate the values an array of chars
from within the scope of a function so that they persist?
foo(char *** list){
// manipulate list elements
}
I assume if I allocate memory with "new", for example...
(*array)[i] = new char[256];
....how can I then free the memory? I assume "delete [] list" won't do
it.
Thanks!!!
Rob ro*************@telefonica.net skrev:
TB wrote:
>You're assigning the address of 'buf' to each pointer, and 'buf' only exists within the scope of 'foo()', not outside in 'main()'. The address points to some location on the stack, which is recycled and overwritten by subsequent stack operations, like the following call to std::basic_ostream::operator<<(...).
You need to allocate the buffer with 'new' if you want it to persist, or dismiss any thoughts of efficiency and do as others have replied, skip deep indirection and use the provided framework of containers.
TB @ SWEDEN
Thanks to you and others who have got back to me. I'll take this
advice; but I'm still curious as to the following:
Essentially: is it possible to manipulate the values an array of chars
from within the scope of a function so that they persist?
foo(char *** list){
// manipulate list elements
}
I assume if I allocate memory with "new", for example...
(*array)[i] = new char[256];
...how can I then free the memory? I assume "delete [] list" won't do
it.
#include <iostream>
#include <ctime>
#include <cstdlib>
void foo(char **& array, unsigned cnt){
for(unsigned i = 0; i < cnt; ++i){
char * buf = new char[256];
long t = std::time(0);
std::itoa(t, buf, 10);
array[i] = buf;
std::cout << i << " " << array[i] << std::endl;
}
}
int main(int argc, char ** argv){
unsigned cnt = 10;
char ** list = new char*[10];
foo(list, cnt);
for(unsigned i = 0; i < cnt; ++i) {
std::cout << i << " " << list[i] << std::endl;
}
for(unsigned i = 0; i < cnt; ++i) {
delete[] list[i];
}
delete[] list;
return 0;
}
--
TB @ SWEDEN
#include <iostream>
#include <ctime>
#include <cstdlib>
void foo(char **& array, unsigned cnt){
for(unsigned i = 0; i < cnt; ++i){
char * buf = new char[256];
long t = std::time(0);
std::itoa(t, buf, 10);
array[i] = buf;
std::cout << i << " " << array[i] << std::endl;
}
}
int main(int argc, char ** argv){
unsigned cnt = 10;
char ** list = new char*[10];
foo(list, cnt);
for(unsigned i = 0; i < cnt; ++i) {
std::cout << i << " " << list[i] << std::endl;
}
for(unsigned i = 0; i < cnt; ++i) {
delete[] list[i];
}
delete[] list;
return 0;
}
--
TB @ SWEDEN
Thanks very much TB!!!
Rob This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Alex Vinokur |
last post by:
Various forms of argument passing
=================================
C/C++ Performance Tests
=======================
Using C/C++ Program Perfometer...
|
by: jr |
last post by:
Sorry for this very dumb question, but I've clearly got a long way to go!
Can someone please help me pass an array into a function. Here's a starting
point.
void TheMainFunc()
{
// Body of...
|
by: BlindHorse |
last post by:
Help!!!
I need someone to tell me why I am getting the err msg
error C2440: '=' : cannot convert from 'char *' to 'char'
//====================
#include <iostream>
|
by: Oeleboele |
last post by:
OK, I can't understand this exactly:
I have this function: int howdy(void *)
I first past this to the function &aCharArray
I realized later that this should be aCharArray but...
the former...
|
by: Jeff K |
last post by:
Can you pass an int array by reference to a function and modify
selective elements?
Here is my code:
#include <stdio.h>
#define COLUMNSIZE 30
#define ASIZE 5...
|
by: intrepid_dw |
last post by:
Hello, all.
I've created a C# dll that contains, among other things, two functions
dealing with byte arrays. The first is a function that returns a byte
array, and the other is intended to...
|
by: Martin Jørgensen |
last post by:
Hi,
In continuation of the thread I made "perhaps a stack problem? Long
calculations - strange error?", I think I now got a "stable" error,
meaning that the error always seem to come here now...
|
by: Christian Maier |
last post by:
Hi
After surfing a while I have still trouble with this array thing. I
have the following function and recive a Segmentation fault, how must
I code this right??
Thanks
Christian Maier
|
by: cpptutor2000 |
last post by:
Could some C guru please help me?
I have a function that takes as an argument a pointer to an array of
unsigned chars (basically a hex representation of a dotted decimal IP
address). When I print...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: giovanniandrean |
last post by:
The energy model is structured as follows and uses excel sheets to give input data:
1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
|
by: GKJR |
last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...
| |