Guidance
指路人
g.yi.org
Guidance Forums / wxWidgets (wxWindows) in C++ / function can't return array?

Register 
注册
Search 搜索
首页 
Home Home
Software
Upload

  
Forum List • Thread List • Reply • Refresh • New Topic • Search • Previous • Next First 1 Last
Message1. function can't return array?
#3148
Posted by: mooncake 2003-12-31 22:05:40


wxString *seeMe() {
   wxString data[5];
   data[0]="A";
   data[1]="B";
   data[2]="C";
   data[3]="D";
   data[4]="E";
  
   return data;

};

51 C:testtest.h
[Warning] address of local variable `data' returned

130 C:testtest.h
ambiguous overload for `wxString& = wxString*' operator

How to do?  Thank you.

Happy New Year to Everyone~ :)
Meow~
Message2. Re: function can't return array?
#3153
Posted by: upCASE 2004-01-01 00:58:53
Hi!
[Warning] address of local variable `data' returned
True. And where did 'data' go after the fuction returned? It was removed from the stack, so it can't be read.

Have a look at this little prog

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

char* f(char*);
string* g(string* s);
string h();

int main()
{
    char* ip = new char[5];
    ip=f(ip);
    cout << ip << endl;

    string* s = new string[2];
    s=g(s);
    cout << s[0] << s[1] << endl;
    
    string s2 = h();
    cout << s2 << endl;
    
    system("pause");
    return 0;
}

char* f(char* i)
{
    i[0]='a';
    i[1]='b';
    i[2]='c';
    i[3]='d';
    i[4]='e';
    
    return i;
}

string* g(string* s)
{
    s[0] = "Hello";
    s[1] = "World";
    return s;
}

string h()
{
    char c[3];
    c[0]='A';
    c[1]='B';
    c[3]='n';
    return c;
}

It's not that good, I just made this up in a few seconds.
Maybe consider using wxArrayString for you task or use a std::vector<wxString>.

upcase
upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message3. Re: function can't return array?
#3158
Posted by: mooncake 2004-01-01 09:51:11
Hi Upcase, when i use wxArrayString, no error, but, the exe file which compiled, caused the error and going down....
Meow~
Message4. Re: function can't return array?
#3159
Posted by: mooncake 2004-01-01 10:33:44
wxArrayString seeMe() {
    wxArrayString data;
    data[0]="Hello";

    return data;
};



bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame(_T("Minimal wxWindows App"),
                                 wxPoint(50, 50), wxSize(450, 340));

    wxArrayString data;
    data=seeMe();
    wxMessageBox(data[0],"A");

    return TRUE;
}

it is free error when i compile it, but, if i run the exe file, system error, ask me wanna report to Microsoft or not.

i dont know what happen... Thank you.
Meow~
Message5. Re: function can't return array?
#3160
Posted by: mooncake 2004-01-01 11:53:10
I did it.. ^^

static wxString data[3];
------

i forgot to use "static"

quite long time no touching c/c++

:)
Meow~
Message6. Re: function can't return array?
#3161
Posted by: mooncake 2004-01-01 13:53:41
But, why can't we passing dynamic size inside?

wxString *seeMe() {
   int i=2;
   static wxString data;
   data[0]="AAA";
   data[1]="BBB";
  
   return data;
};

if i replace static wxString data to wxString *data;
it will caused the program down... :(

What can i do now??

Thank you
Meow~
Message7. Re: function can't return array?
#3164
Posted by: upCASE 2004-01-01 23:27:55
Hi!
Firstly: Would you mind to explain what exactly you are trying to do?? To me this makes no sense at all...

About this version:
wxArrayString seeMe() {
    wxArrayString data;
    data[0]="Hello";

    return data;
};
Sure, this crahes. Have you ever debugged it?
wxArrayString is a type for storing a variable count of wxStrings, overloading operator[] so that you can access elements like in a normal array. But unlike a normal array wxArrayString is dynamic container. This means you can compare it to other container types like vector.
Problem is, that when you do a data[0]="Hello", this is syntactically fine, so no compiler errors or warnings. But logically this is not correct. At the moment when you want to assign "Hello" to data[0], there is no memory space reserved for data[0], so it crashes. Using data.Add("Hello"); it works perfectly fine, because Add() allocates the needed memory.
Try
wxArrayString seeMe() {
    wxArrayString data;
    data.Add("Hello");
    data[0]="World";

    return data;
};
it works!

About maing things static: Sure, this is allways a way to do it. But I wouldn't recomment to use static vars all over the place...

"wxString *seeMe() {
   int i=2;
   static wxString data;
   data[0]="AAA";
   data[1]="BBB";
  
   return data;
};

if i replace static wxString data to wxString *data;
it will caused the program down... :("
You mean writing "static wxString* data" instead of "static wxString data"??? Sure this will crash...
BTW, I think you meant "static wxString data[2]", otherwise it won't even compile... About int i, you can't use it like "
static wxString data[i]
", because size identifiers for arrays have to have a concrete size, so no variables here.

Just a question: Why do you want to create everything on the stack? Why not create it dynamically on the heap??
Personally I see no use of this at all, because if there is a self managed type like wxArrayString that handles allocation and deallocation of memory, I suggest that you use it for safety issues. And even if there wasn't such a thing, I would use a vector<wxString>.
But ok, here's a version that dynamically creates an array the C++ way and returns a pointer to that array. Be sure to delete the pointer to that array somewhere in your code when you don't need it anymore. Otherwise it will stay in memory till the program terminates.
Debug this version to see what I mean. Pay attention to the adress change of 'd' after the second call to seeMe(). A new pointer is generated, but the memory of the old one is never deleted.

wxString *seeMe(int i) {
   
   wxString* data = new wxString[i];
   data[0]="AAA";
   data[1]="BBB";
      
   return data;
};

bool MainApp::OnInit()
{
   MainFrame *frame = new MainFrame(_T("Minimal wxWindows App"),
                                 wxPoint(50, 50), wxSize(450, 340));
    frame->Show(true);

    wxString* d;
    d=seeMe(2);
    wxMessageBox(d[0],"A");
    wxMessageBox(d[1],"A");
    
    d=seeMe(2);
    
    return TRUE;
}
BTW: I'd suggest that you read again about arrays and pointers, because this is not a problem with wxWindows or its types, but with understanding what an array of objects or a pointer really is.

upcase
upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message8. Re: function can't return array?
#3170
Posted by: mooncake 2004-01-02 18:18:23
Hi Upcase,
    Hmm... thats PHP likes coding method... :p
    Possibe that to return two dimention variable from the function and how?

Thank you.
Meow~
Message9. Re: function can't return array?
#3171
Posted by: KaReL 2004-01-02 19:50:59
pass them by reference... A function can return only 2 variables in 1 way:
1 variable by normal returning, another by throwing an error with the second variable. Another way to do is using a struct (which you return, which again is in essence, returning 1 variable).

Here is a good C++ reference site:
http://www.informit.com/isapi/product_id~%7B47F49395-D3D7-45CA-A2EB-68A6EF6B16CB%7D/content/index.asp

It handles about everything you need to know (though it ain't for starters)

------------------------
Website: www.KaReLs0ft.be
Message10. Re: function can't return array?
#3173
Posted by: mooncake 2004-01-02 20:15:11
Hi KaReL,

In PHP method, we can use like this:

function abc() {
     $a[0][0]="AAA";
     $a[1][0]="BBB";

     return $a;
}

$get=abc();

echo $get[0][0];

So, i thought CPP can do like this also... :(

One dimension variable can return now, but, two-dimension still can't even if i use wxArrayString

But anywhere, thank you for your suggesstion... :)
Meow~
Message11. Re: function can't return array?
#3174
Posted by: KaReL 2004-01-02 21:40:11
Thou shalt not it can't be possible!

Ever thought about a wxArray in a wxArray? :p

I assure you it's possible... Though not easy...

It should be something like this: (exact syntax and working program look elsewhere, this is just a few thoughts I have)

--h--
#include <wx/dynarray.h>
WX_DECLARE_OBJARRAY(wxString, InnerArray);
WX_DECLARE_OBJARRAY(InnerArray, OuterArray);

--cpp--
#include <wx/arrimpl.cpp>
WX_DEFINE_OBJARRAY(OuterArray);

It should mean something like:
typedef std::vector<std::vector<wxString>> OuterArray;

which you should be able to access like:

OuterArray[0][0] = wxT("ABC");

(be carefull though that you keep in mind upCASE his post here above about not adding/assigning this way).

You should add first strings to the innerarray, than add that innerarray to the outerarray:
mInnerArray.Add( wxT("String1") );
mInnerArray.Add( wxT("String2") );

OuterArray.Add(mInnerArray);


Yet again... I don't know why you should make life so difficult... Create your own class & do all you need to do in there... That should do the trick better then any of the internal classes.

------------------------
Website: www.KaReLs0ft.be
Message12. Re: function can't return array?
#3175
Posted by: mooncake 2004-01-02 22:12:37
Hi KaRel,

it promt me this...

 
[Linker error] undefined reference to `InnerArray::~InnerArray()'



actually, this function is retrieved from class... :p

Thank you..
Meow~
Message13. Re: function can't return array?
#3176
Posted by: KaReL 2004-01-03 00:44:41
Sorry, but I will not try any further to solve your problem. (Yes you read it good, I will not try to solve your problem). I want to try to point you into some kind of direction, give you some advice, but I will not create your programs, nor will I try to give you a cut-and-paste example.

Because really, the thing you want is easy to accomplish, but has nothing to do with wxWindows any more. It's something that is elemental C++.

It might be obvious to me how to continue, as it might stay unclear for you how to continue.


Maybe if you say why you want to return such a thing (a multidimension thingie), I could give you some advice in how or what to use.

I want to help you, not think for you.

------------------------
Website: www.KaReLs0ft.be
Message14. Re: function can't return array?
#3178
Posted by: upCASE 2004-01-03 02:56:20
Hi!
Well, although I didn't want to spend more time on this prob (KaReL is right: It has nothing to do with wxWindows, but it's NOT elemental C/C++ unless you're named Kernighan, Ritchie or Stroustrup...), I had another look into the matter and I must confess that it's not that trivial to me either. In fact I found it quite interesting... maybe I'm too nerdish and should get a life :)

There are a few things I want to comment on. If I'm not correct, feel free to correct me in return :)
Hmm... thats PHP likes coding method... :p
In PHP method, we can use like this:
function abc() {
     $a[0][0]="AAA";
     $a[1][0]="BBB";

     return $a;
}
$get=abc();
echo $get[0][0];
So, i thought CPP can do like this also... :(
One dimension variable can return now, but, two-dimension still can't even if i use wxArrayString
First of all, what I did isn't PHP like coding. I don't think you can compare the memory handling of PHP to C/C++/Java, for the simple fact that PHP is basically typeless or loosely typed, while the others are "strongly typed". A variable in PHP could be anything, it's a question of how you interpret its value. In C/C++ the type (and so the value) of a variable is clear.
Yes, you can do something like that in C/C++. It's basically the same thing compared to my example I gave before. Later on I'll post a small example.
About wxArrayString: Would you mind to clearify what exactly you want to do?? First it was about returning a dynamically created array, now what? Return an array of an array of strings?? That would mean returning an array of wxArrayString in a wxWindow context. What's the point/trouble?
A function can return only 2 variables in 1 way:
1 variable by normal returning, another by throwing an error with the second variable. Another way to do is using a struct (which you return, which again is in essence, returning 1 variable).
Yikes! "Return" a variable by throwing? Well, even though this is possible, it's a thing to avoid. Exception handling should be used for exceptions, not for throwing variables all over the place... In that case I could change to using global variables and gotos... Just don't do it.
Even if you could return a variable by throwing, this would still be only one variable, because the second (the return value) got never be returned. You would have to throw the first one before the return, thus leaving the function going to the catch(). There would be no return.
Using a struct is surely a way, but as you said later on, using a class in C++ would be better.
I'd suggest using pointers or references (whatever you like best) if you need to change more than one variable.
[Linker error] undefined reference to `InnerArray::~InnerArray()'
Sure, if you only copied KaReLs code...
It tested this and it works perfectly.

#ifndef __BASE_H
#define __BASE_H

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
   #include <wx/wx.h>
#endif
#include <wx/dynarray.h>

class MainApp: public wxApp
{
  public:
      virtual bool OnInit();
};

WX_DECLARE_OBJARRAY(wxString, InnerArray);
WX_DECLARE_OBJARRAY(InnerArray, OuterArray);
#endif //__BASE_H

------CPP file-------
#include <wx/arrimpl.cpp>
#include "base.h"

IMPLEMENT_APP(MainApp)
WX_DEFINE_OBJARRAY(InnerArray);
WX_DEFINE_OBJARRAY(OuterArray);

bool MainApp::OnInit()
{
    InnerArray inner;
    inner.Add("Hello");
    inner.Add("World");
    
    OuterArray outer;
    outer.Add(inner);
    
    inner.Clear();
    inner.Add("Goodbye");
    inner.Add(", I'm leaving now...");
    
    outer.Add(inner);
    
    wxMessageBox(outer[0][0] + " " + outer[0][1]);
    wxMessageBox(outer[1][0] + " " + outer[1][1]);
    
    return FALSE;
}

Here'a another snippet that might be usefull

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

typedef vector< vector<int> > Int;

int** allocfill();
Int test();

int main()
{
    int** ar = allocfill();
    for(int j=0; j < 5; j++)
    {   cout << endl;
        for(int i=0; i < 5; i++)
            cout << ar[j][i] << "t";
    }
    cout << endl;
    
    Int vec = test();
    for(int i=0; i < 5; i++)
    {    cout << endl;
        for(int j=0; j<5;j++)
            cout << vec[i][j] << "t";
    }
    
    system("pause");
    return 0;
}

Int test()
{
    vector<int> i(10,0);
    Int ar(10,i);
    
    for(int i=0; i < 5; i++)
        for(int j=0; j<5;j++)
            ar[i][j]=i+j;
    
    return ar;
}

int** allocfill()
{
    int** array = new int*[5];
    for(int i=0; i < 5; i++)
        array[i] = new int[5];
    
    for(int j=0; j < 5; j++)
        for(int i=0; i < 5; i++)
            array[j][i] = i+j;
    return array;
}

I'm willing to help, too. Maybe I pushed this too far... Google for Array2D for a template class that might be usefull.
Anyway, I strongly suggest that you grab a good book and read about pointers/arrays/references and rethink your apps design.

upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message15. Re: function can't return array?
#3179
Posted by: KaReL 2004-01-03 03:59:22
Quote from upCASE

Yikes! "Return" a variable by throwing?


;) I didn't tell anyone to do it... I just told it's possible :p ... Oh no, you're right... There won't be any return (stupid me)... But you can return 2 types of variables this way, but as you said: referencing is WAYS better

Quote from upCASE

Do. Or do not. There is no try!


You stole my line!



Post Edited (01-03-04 04:00)
------------------------
Website: www.KaReLs0ft.be
Message16. Re: function can't return array?
#3180
Posted by: upCASE 2004-01-03 04:42:53
Hi!
A nice comprehensive tutorial on pointers:
http://pw1.netcom.com/~tjensen/ptr/pointers.htm

upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message17. Re: function can't return array?
#3184
Posted by: mooncake 2004-01-03 18:49:59
Hi guys, finally, i got my answer.  Thanks to you guys show me the tips... :)

this is what i want:

wxArrayString seeMe(int dt) {
   wxArrayString data[2][1];
   data[0][0].Add("Hello");
   data[1][0].Add("EE");
  
  
   return *data[dt];

};

this is not a good solutions, but, i will try to improve this.

and... actually.. i had tried at least 3 days about this stuff, non-stop doing researching and testing...

:)
Meow~
Message18. Re: function can't return array?
#3185
Posted by: KaReL 2004-01-03 20:23:53
Yikes!

Allow me to puke :)


What you do is the following:
Create 2 wxArrayString's ([0][0] & [1][0]) ... To both you add 1 string, then you return the [dt][0] (you could better write: return data[dt][0];, it's easier to read).

Why do I say Yikes to this?

Because you do a lot of unneccessary work ... It will work! Congratz on that ...

Upon "returning" the stringarray, you will make a copy of that array...


Still, I don't know what you're trying to accomplish, therefor I cannot properly suggest an alternative.

------------------------
Website: www.KaReLs0ft.be
Message19. Re: function can't return array?
#3186
Posted by: mooncake 2004-01-03 22:11:33
Hi KaRel,

I will do that, becuase...

wxArrayString test;

test=seeMe(1);

wxMessageBox(test[0]);

Thats why.

Meanwhile, i dont understand what happen to this...

wxArrayString SQL::Data(int flt){
   unsigned int num_fields;
   int i;
   int y;
   int x=(int) mysql_num_rows(this->res);
   num_fields = mysql_num_fields(res);
   wxArrayString data[x][num_fields];

  
   for (i=0;i<=x;i++) {
       this->GetRow();
       data[1].Add(this->row[1]);
   }
   return *data[flt];
};

if running it, will caused the program down.... i dont understand this...

if drop "for loop", it is no problem to me....

I am still trying to debugging and solve this problem...

Thank you.. :)
Meow~
Message20. Re: function can't return array?
#3187
Posted by: KaReL 2004-01-03 23:53:44
YIKES!
an arraystring made of x rows & y fields!!! YIKES

*faint* omg!

better would be to use
wxArrayString data[musql_num_rows(res)];

and then
for i = 0 -> num-fields { GetRow(); data[rowID].Add(row[i]); }
Or something like that... But jakkes!

A small but useful hint maybe: try to write down above every line what it does like:
// get the number of rows i have selected in my current query
   int x=(int) mysql_num_rows(this->res);
// I like wasting memory, so who cares?
  wxArrayString data[x][num_fields];

:p and so on.

But I'll leave you now for this project. I'll leave you be...

There is one good source for your answers out there though:

http://www.google.com


You should try it someday!

------------------------
Website: www.KaReLs0ft.be
Forum List • Thread List • Reply • Refresh • New Topic • Search • Previous • Next First 1 Last
掌柜推荐
 
 
 
 
 
 
 
 
 
 
 
 
© Fri 2024-3-29  Guidance Laboratory Inc.
Email:webmaster1g.yi.org Hits:0