a vector of void pointers which point to array of characters

Pages: 12
This code work perfectly, as follows.

Code #A:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;


typedef std::vector <void *> gr_vector_void_star;

gr_vector_void_star  output_items;

int noutput_items = 5;


int main()
{
    // initialize output_items[0]
    char* *temp[ noutput_items ];
    output_items.push_back( temp );

    // store values into output_items[0]
    char* *out = (char**) output_items[0];
    out[0] = "A";
    out[1] = "n";
    out[2] = "g";
    out[3] = "e";
    out[4] = "l";

    // retrieve values from output_items[0]
    char* *display = (char**) output_items[0];
    for (int i=0; i < noutput_items; i++)
     { cout << display[i] << endl; }

    return 0;
}


Output of above code #A:
A
n
g
e
l

Process returned 0 (0x0)   execution time : 0.002 s
Press ENTER to continue.


To do it in a smarter way, I change the line 22 to 26 above to this:
1
2
3
    char * sentence = "Angel";
    for (int i=0; i < 5; i++)
     { out[i] = sentence[i]; }    // error: invalid conversion from 'char' to 'char*'  [-fpermissive] 

It fails to compile with error message "invalid conversion from 'char' to 'char*'".


Question: How to correct this error?
Last edited on
Why is your code so needlessly convoluted for this? Why are you even using void pointers at all? Also, you're converting from char const * to char * on lines 22-26, which isn't allowed.
Last edited on
@LB:
Why is your code so needlessly convoluted for this? Why are you even using void pointers at all?

Answer:
This is part of the source code of GNU Radio. We have no choice but live with what it is.
http://gnuradio.org/doc/doxygen-3.3.0/gr__types_8h.html
Last edited on
Ah, I'm sorry you're stuck using code like that.

The problem is that lines 22-26 each assign a different string, whereas in your loop you are trying to assign a different character. I suggest a redesign.
@LB:
Also, you're converting from char const * to char * on lines 22-26, which isn't allowed.

Thanks for pointing out. It can be corrected easily, refer below code.
It works and produce same output as code #A above.

Code #B
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;


typedef std::vector <void *> gr_vector_void_star;

gr_vector_void_star  output_items;

int noutput_items = 5;


int main()
{
    // initialize output_items[0]
    const char* *temp[ noutput_items ];
    output_items.push_back( temp );

    // store values into output_items[0]
    const char* *out = (const char**) output_items[0];
    out[0] = "A";
    out[1] = "n";
    out[2] = "g";
    out[3] = "e";
    out[4] = "l";

    // retrieve values from output_items[0]
    const char* *display = (const char**) output_items[0];
    for (int i=0; i < noutput_items; i++)
     { cout << display[i] << endl; }

    return 0;
}


Last edited on
I don't understand what compiler you're using that allows invalid code like this - on line 11 the variable is not constant but on line 17 you use it for a stack array.

The only way with your current design to do what you want involves really messy memory management. Find a more high level solution if possible.
@LB:
I don't understand what compiler you're using that allows invalid code like this

Answer:

$ g++ --version
g++ (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ uname -a
Linux rsLAPTOP 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux
Last edited on
If you don't specify a specific version of the C++ standard to use you default to using GNU language extensions ;) try -std=c++03 or -std=c++11
man wrote:
-Wpedantic
-pedantic

Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.

Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the required version of ISO C). However, without this option, certain GNU extensions and traditional C and C++ features are supported as well. With this option, they are rejected.
If you want it to generate an error -pedantic-errors


You're trying to do X, and you thought of solution Y. So you're asking about solution Y, without even mentioning X. The problem is, there might be a better solution, but we can't know that unless you describe what X is.
Last edited on
closed account (z05DSL3A)
activecat,

With this thread and your other [1], I am unclear as to what you are trying to achieve, what data you have control over, what parts of the code is simulating data received, etc.

Any chance that you could give some more detail?

______________________________________________
[1] http://www.cplusplus.com/forum/general/121950/#msg664440
@Canis lupus:
With this thread and your other [1], I am unclear as to what you are trying to achieve, what data you have control over, what parts of the code is simulating data received, etc.

Let's assume [1] doesn't exist, because [1] is trying to describe exactly the same problem, which is still unsolved at this moment.
In this thread I try to rephrase the question, because I might have provided wrong information in [1].
In fact the code in this thread is same with the one in [1], except that it is further simplified here.




(A). The parts that I do NOT have control over:

1). The data type of output_items must be defined in this way (we cannot change the source code of GNU Radio)
1
2
typedef std::vector <void *> gr_vector_void_star;
gr_vector_void_star  output_items;

2). These data must be stored in such a way that each of them is exactly one character.
What we are in control is how out is defined and how it was manipulated.
Earlier it worked fine when I was using:
1
2
3
4
5
    out[0] = "A";
    out[1] = "n";
    out[2] = "g";
    out[3] = "e";
    out[4] = "l";

Then I try to play smart by doing below , it caused error.
1
2
3
char * sentence = "Angel";
    for (int i=0; i < 5; i++)
     { out[i] = sentence[i]; }

This (above error) is the problem that we need to solve.


3). The above stored data must be referenced by output_items[0] whenever we want to retrieve it later.

4). The output_items.push_back(temp) must be performed before temp, out and display are defined, because the former is part of GNU Radio source code whereas the latter (temp, out and display) is user-defined.




(B). The parts that are up to us to define:

1). data type of temp and how it is manipulated
2). data type of out and how it is manipulated
3). data type of display and how it is manipulated
Last edited on
@ne555
You're trying to do X, and you thought of solution Y.

The [1] and this thread are talking about the same problem. No solution exists so far.
I might have provided wrong information in [1], that's why it is easier to start over again, by ending [1] and then create this thread. This will be cleaner.
Last edited on
try this:
1
2
3
4
52                 char* temp = (char*)malloc(2*sizeof(char));
 53                 strncpy(temp, sentence+i, 1);
 54                 temp[1] = '\0';
 55                 out2[i] = temp;


here make a c string temp to store char of sentence, to avoid the invalid conversion error.
closed account (z05DSL3A)
activecat,

I don't know if this will help you figure out what you want to do...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>


typedef std::vector <void *> gr_vector_void_star;


int main()
{
    gr_vector_void_star  output_items;

    /////////////////////////////////
    // 
    const size_t out_size = 5;
    char out[out_size];

    out[0] = 'A';
    out[1] = 'n';
    out[2] = 'g';
    out[3] = 'e';
    out[4] = 'l';

    output_items.push_back(out);

    ////////////////////////////////
    //
    const char* sentence("Angel");
    char out2[out_size];
    for(size_t i = 0; i < out_size; ++i)
    {
        out2[i] = sentence[i];
    }

    output_items.push_back(out2);  // edit 

    ////////////////////////////////
    //
    char * display = static_cast<char *>(output_items[0]);
    for(size_t i = 0; i < out_size; ++i)
    {
        std::cout << display[i] << std::endl; 
    }
    
    std::cout << std::endl;

    display = static_cast<char *>(output_items[1]);
    for(size_t i = 0; i < out_size; ++i)
    {
        std::cout << display[i] << std::endl; 
    }
}
Last edited on by Canis lupus
@Canis lupus:
Your line 34 above should be output_items.push_back(out2) instead.
closed account (z05DSL3A)
Yes, it should. :0)
I don't know if it is an error, but in all c++ compilers I used since second half of 1990s a code like

1
2
int a = 5
char q[a];


ALWAYS works without errors nor warnings (I don't know what happens if you use -pedantic... I say what happens if you compile in a "standard" way)

This becouse when you decide the dimension of an array, the important thing is that, AT THAT MOMENT, a value is defined: either using a number or using an integer variable (can be also not an int) that actually has assigned a value (but it is not needed that the variable must be const).

This becose if you change later the value of "a" the dimension of array was already defined before (so... if after char q[a] the value a will be 10, char q[a] will obliouvsly remain an array of 5 char values).

It is the same mechanism when you use a function that expects a const int. You can pass a non-const int value, but the function will copy its value into its own const-int value parameter and will treat internally that value as a const value.
Nobun wrote:
In all c++ compilers I used since second half of 1990s a code like
1
2
int a = 5
char q[a];
ALWAYS works without errors nor warnings


There are more compilers out there:

1
2
3
4
5
int main()
{
   int a = 5;
   char q[a];
}

$ CC -o test test.cc
"test.cc", line 4: Error: An integer constant expression is required within the array subscript operator.
1 Error(s) detected.
$ CC -V
CC: Sun C++ 5.10 SunOS_sparc Patch 128228-25 2013/02/20


Granted, one of the main reasons ISO exists is to standardize existing language extensions and this almost became valid C++14, but not yet.
Last edited on
@activecat: still have no idea what you are trying to do.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::string message = "the quick brown fox jumps over the lazy dog";
std::vector< const char * > out( messgae.size() );

//making the portions zero-terminated
std::string aux( 2*message.size() );
for(int K=0; K<message.size(); ++K){
   aux[2*K] = message[K];
   aux[2*K+1] = '\0';
}

for(int K=0; K<out.size(); ++K)
   out[K] = &aux[2*K];

//or if you don't care about zero terminated
for(int K=0; K<out.size(); ++K)
   out[K] = &message[K];

//why can't you simply
out[0] = &message[0];
¿how are you planning to use it?

> These data must be stored in such a way that each of them is exactly one character.
¿zero terminated?
The data is already in the `sentence' variable. I don't see the point in duplicate it.

> The parts that are up to us to define:
> 1). data type of temp and how it is manipulated
> 2). data type of out and how it is manipulated
> 3). data type of display and how it is manipulated
¿to do what?


> (we cannot change the source code of GNU Radio)
if it's gnu, you can
@ne555
still have no idea what you are trying to do.

If you don't mind to read the longer story, refer GNU Radio documentation below:
http://gnuradio.org/redmine/projects/gnuradio/wiki/OutOfTreeModules#The-C-code-part-1

Basically I try to build two blocks, namely a transmitter and receiver.
The transmitter block will send out "A", "n", "g", "e", "l"; byte-by-byte, repeatedly.
The receiver block will receive the bytes and send them to std::cout.

The above-discussed code will be implemented in function general_work().
Last edited on
Pages: 12