0

I am reading a void* to a memory address from a pipe. The memory address is that of a char* as seen below.

char *text=getStringFromFunction(params);
void *adrs=&text;
write(pipefd[1], adrs, sizeof(char *));

Now I am trying to print out the text on the other side of the pipe, but I am unsure how to get a hold of the char* with only the memory address. This is all within the same process, so I believe I should be able to access the address space with just the pointer to it. Below is one of my attempts

void *buf;
read(pipefd[0], buf, sizeof(char *));
fprintf(stdout, "buf=%s", (char *) buf);

But it yields garbage results. Again, I could find nothing relevant to this topic on the search and Thanks for the help in advance!

Clark
  • 43
  • 1
  • 1
  • 5
  • 4
    Each process has it's own virtual address space, which leads to other physical memory. The value of a pointer in a process is completely meaningless in another process. – mch Dec 08 '15 at 15:13
  • Try writing the data to the pipe instead of the address. – Klas Lindbäck Dec 08 '15 at 15:19
  • This will all be within a single process, thanks for the tip though. The data will be rather large so I'm avoiding passing it through the pipe – Clark Dec 08 '15 at 15:20
  • What is `buf` in the first section of your code? And `adrs` in the second section? I think you have them the wrong way round. – Ian Abbott Dec 08 '15 at 15:21
  • In the first snippet you prep the variable `adrs` and then write `buf` to the pipe. In the second snippet you read `adrs` from the pipe and then print `buf`. I find that very confusing. – Klas Lindbäck Dec 08 '15 at 15:25
  • You're absolutely right, changing it now. The problem still persists – Clark Dec 08 '15 at 15:28
  • When you say "same process", do you by any chance mean code involving `fork`? Because that spawns new processes -- Linux has no concept of threads. Either way this isn't an issue of passing the pointer, the memory itself isn't being shared. – Blindy Dec 08 '15 at 15:31
  • Why are you using `void *`? – Karoly Horvath Dec 08 '15 at 15:38
  • No forking in the program – Clark Dec 08 '15 at 15:54

3 Answers3

0

You pass pointer to char* (i.e. char**) not char*. Try void adrs = (void)text.

0

In:

char *text=getStringFromFunction(params);
void *adrs=&text;

adrs is the address of variable text, not the char* it points to.

That address is no longer valid when this function returns. This address is never valid in another address space.

You may like change it to void *adrs=text, that would send a pointer to a string through the pipe. This pointer is only valid in the same process.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

If this is in the same process where, for example one thread is writing the buffer address through the pipe and a second thread is reading from the pipe to get the buffer address (basically you are using the pipe as a kind of FIFO queue of buffer addresses) then I would use the following.

char *text=getStringFromFunction(params);  // get the pointer to the string
int  nByteWritten = 0;
nByteWritten = write(pipefd[1], &text, sizeof(char *));    // write the pointer into the pipe

Then when reading the buffer I would do something like the following. When doing the read() you need to provide the address of the char * pointer.

char *buf;
int  nByteRead = 0;
nByteRead = read(pipefd[0], &buf, sizeof(char *));   // get the address from the pipe
fprintf(stdout, "buf=%s", buf);          // print the string

Not sure if the printing section of code needs to worry about freeing or releasing the pointer or not.

For between two programs see How to send a simple string between two programs using pipes?

Community
  • 1
  • 1
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
  • Hm, I gave this a go but it's throwing a segfault. Doing a core trace shows the problem is in that last fprintf trying to print 'buf' – Clark Dec 08 '15 at 18:01
  • @Clark Can you run it in a debugger and see what is being written to the pipe and what is being read from the pipe? – Richard Chambers Dec 08 '15 at 18:08
  • @Clark another question is whether the pointer is still valid at the point where the `fprintf()` is being done. – Richard Chambers Dec 08 '15 at 18:09
  • Yeah, it's switching the address space, being written is: dump=0x7fffec0008c0 and being read: &buf=0x7ffff69e0e18 – Clark Dec 08 '15 at 18:28
  • @Clark could you provide more details so that I can understand what you mean by "switching the address space"? Is the value of the pointer that is written to the pipe the same value as is read from the pipe? Is the address which is read from the pipe still a valid address meaning that it is all within the same process and the pointer address has not been freed or otherwise become invalid? – Richard Chambers Dec 08 '15 at 18:30
  • @Clark ok so what is being read from the pipe is not the same as is being written to the pipe. hmmm. wait a minute. address of `buf` is not what you want but rather the value of `buf` after the read from the pipe. – Richard Chambers Dec 08 '15 at 18:32
  • Ah, apologies but I'm a bit awful with knowing which symbol to use to get values vs addresses. How would I arrange them to get the value of buf after the read? I've been shotgunning the different types to no avail thus far. – Clark Dec 08 '15 at 18:41
  • @Clark since you are writing to `stdout` anyway just go ahead and print the value of `text` at the point where you write it to the pipe and then after doing the read from the pipe print the value of `buf`. You would use the `%p` formatting directive to print a pointer value as in `fprintf (stdout, "text = %p\n", text);` and similarly for `buf`. Notice the `\n` to flush the output line. – Richard Chambers Dec 08 '15 at 18:45
  • I appreciate the help thus far, feel like Im making some good headway here. As for the output, it will end up going to other places aside from stdout. I'm not so much interested in printing the pointer values but I want to get back to the string that is stored at that memory address. – Clark Dec 08 '15 at 18:57
  • @Clark, I understand that you want the string stored at the memory address. However there is the segfault which is typically caused by two major issues with strings. The first is a bad pointer to the string and the second is the string not being terminated by a binary zero. The question is whether the pointer value read from the pipe is the same was what was written to the pipe. Either you need to figure out how to view the value of a variable using the debugger to see what the value of variables are at those points or you need to print them as a debug write which will later be removed. – Richard Chambers Dec 08 '15 at 19:00
  • before write, `text=0x7f7e6c000d10`; but after Reading, `buf=nil`. – Clark Dec 08 '15 at 19:08
  • @Clark, buf having a value of nil would certainly explain the segfault. I modified the lines of code to capture number of bytes read and number of bytes written. Make same modification to your code and print out the results so that we can see whether proper number of bytes being written and read. Also is pipe blocking or non-blocking? – Richard Chambers Dec 08 '15 at 19:15
  • Hey, that one did the ticket mate! What you have edited it to is now functioning properly to what I needed! Outstanding work, I was stuck with this bothersome thing for countless hours – Clark Dec 08 '15 at 19:41
  • @Clark, glad to hear it. Sorry it was so much effort! Good luck for the future. – Richard Chambers Dec 08 '15 at 19:42