Juliano Oliveira
Juliano Oliveira

Reputation: 928

Double pointer as parameter

I have the follow prototype:

int Split(const char* str, const char* delim,unsigned int& numtokens,char **tokensRes)

The last parameter is used to return the response of this function. In the function we have the follow:

.
.
char **tokens =(char**) calloc(tokens_alloc, sizeof(char*));
.
.
.
//at the end of the code
tokensRes = tokens;
.

When returns the value of tokens variable direct when the return of the function is char** I receive the correct answer, but using the method above the return of the function came empty. How can I make this function work correctly?

EDIT 1: My intent is receive an array of char arrays, eg:

array[0] = "ABC"
array[1] = "ABC"
array[2] = "ABC"
array[3] = "ABC"

Upvotes: 0

Views: 1342

Answers (3)

coyotte508
coyotte508

Reputation: 9705

Change the prototype from:

int Split(const char* str, const char* delim,unsigned int& numtokens,char **tokensRes)

To:

int Split(const char* str, const char* delim,unsigned int& numtokens,char ** &tokensRes)

And the code tokensRes = tokens; will work. To understand why learn more about C++ and references.

Other answers about using strings are valid if you're planning to move from a C style of coding to a C++ one. The ease of coding would improve a lot and no worries about memory management and pointers (well not often), which are done automatically by classes. No worries about a performance decrease either as long as you follow good practices such as passing objects by reference and not value.

Upvotes: 2

Jens
Jens

Reputation: 9406

Just ditch the plain C types and use C++ types:

std::vector<std::string> Split(std:;string const& str, std::string const& delim, unsigned int& numtokens);

If you have to stick to the C interface, you need an additional indirection with a triple pointer (I am assuming that you want to return an array of token strings).

int Split(const char* str, const char* delim,unsigned int& numtokens,char ***tokensRes)

char** tokens;
Split("String;String", ";", 2, &tokens);

I really dislike output parameters, and I always wonder why anybody does not use std::string in C++.

Tokenizing has been implemented in many libraries, e.g. in boost::split or boost::tokenizer. No need to reinvent the wheel:

// simple_example_1.cpp
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>

int main(){
   using namespace std;
   using namespace boost;
   string s = "This is,  a test";
   tokenizer<> tok(s);
   for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}

The output from simple_example_1 is:

This
is
a
test

Upvotes: 1

Pezo
Pezo

Reputation: 1448

Assuming you want to return an array of strings (char**), then you need to pass a pointer to such an array that you can assign. That is, you need to pass a char*** and assign it like *tokensRes = tokens.

Upvotes: 1

Related Questions