Thread: CurrentMemoryContext and MemoryContextStrdup

CurrentMemoryContext and MemoryContextStrdup

From
Yessica Brinkmann
Date:
Good Morning,
I have written in the general list on this subject, but since I do not get an answer according to my little knowledge on the subject, I write on this list, since perhaps my question is very basic.
My query is the following: can you please give me some reference (link on the Internet) that explains how CurrentMemoryContext and MemoryContextStrdup is used, and also some example of source code of use?
I've searched the Internet a lot but can't find anything.
It is for a University thesis that I am trying to implement.
Best regards,
Yessica Brinkmann

Re: CurrentMemoryContext and MemoryContextStrdup

From
Tom Lane
Date:
Yessica Brinkmann <yessica.brinkmann@gmail.com> writes:
> I have written in the general list on this subject, but since I do not get
> an answer according to my little knowledge on the subject, I write on this
> list, since perhaps my question is very basic.
> My query is the following: can you please give me some reference (link on
> the Internet) that explains how CurrentMemoryContext and
> MemoryContextStrdup is used, and also some example of source code of use?

I think you'd feel a lot better informed after reading

src/backend/utils/mmgr/README

            regards, tom lane



Re: CurrentMemoryContext and MemoryContextStrdup

From
Yessica Brinkmann
Date:
Thank you very much for the reply!
Not really, I don't feel better informed because MemoryContextStrdup is not even mentioned once in the README.
Best regards,
Yessica Brinkmann

El mar., 26 nov. 2019 a las 13:08, Tom Lane (<tgl@sss.pgh.pa.us>) escribió:
Yessica Brinkmann <yessica.brinkmann@gmail.com> writes:
> I have written in the general list on this subject, but since I do not get
> an answer according to my little knowledge on the subject, I write on this
> list, since perhaps my question is very basic.
> My query is the following: can you please give me some reference (link on
> the Internet) that explains how CurrentMemoryContext and
> MemoryContextStrdup is used, and also some example of source code of use?

I think you'd feel a lot better informed after reading

src/backend/utils/mmgr/README

                        regards, tom lane

Re: CurrentMemoryContext and MemoryContextStrdup

From
Tom Lane
Date:
Yessica Brinkmann <yessica.brinkmann@gmail.com> writes:
> Thank you very much for the reply!
> Not really, I don't feel better informed because MemoryContextStrdup is not
> even mentioned once in the README.

The next thing to do would be to look at that function's header comment
(find it in src/backend/utils/mmgr/mcxt.c):

/*
 * MemoryContextStrdup
 *        Like strdup(), but allocate from the specified context
 */
char *
MemoryContextStrdup(MemoryContext context, const char *string)


As I recall your original problem, people were suggesting that
you make a longer-lived copy of some transiently-allocated
string.  Copying it into a different context would be the
way to do that, as I hope you now understand from the README
discussion, and this function is the easiest way to do that.

Or at least the second easiest; the very easiest is pstrdup,
which is just

char *
pstrdup(const char *in)
{
    return MemoryContextStrdup(CurrentMemoryContext, in);
}

but I don't remember whether the current context was a suitable
target for your use-case.

            regards, tom lane



Re: CurrentMemoryContext and MemoryContextStrdup

From
Yessica Brinkmann
Date:
Thank you very much for your answer.
Well, you told me that pstrdup was not going to help me in the context of my use case.
And that I would have to use MemoryContextStrdup.
And the truth is that this part costs me a bit, even though I have the definitions of MemoryContextStrdup in the .c, since I can't find an example of a source code that uses it, it's hard for me to apply things by definition just.
By telling me: "Copying it into a different context would be the way to do that", I understand better.
Now, as I understand it (I don't know if I'm right), what I would have to do would be this:
1. I save the CurrentMemoryContext, for example as follows:
MemoryContext oldcontext = CurrentMemoryContext;
2. I make the call to SPI, which was what caused the context problem.
3. I copy my variable in a different context, for example as follows:
MemoryContext newcontext;
char * copy = MemoryContextStrdup (newcontext, data);
4. Then, at the end of my call to SPI, after SPI_finish () I would have in the copy variable, the copy of the data variable, to use it as I want.
Is that so? I am correct at least to try to modify my program or is it totally something else what should I do?
Best regards,
Yessica Brinkmann

El mar., 26 nov. 2019 a las 13:48, Tom Lane (<tgl@sss.pgh.pa.us>) escribió:
Yessica Brinkmann <yessica.brinkmann@gmail.com> writes:
> Thank you very much for the reply!
> Not really, I don't feel better informed because MemoryContextStrdup is not
> even mentioned once in the README.

The next thing to do would be to look at that function's header comment
(find it in src/backend/utils/mmgr/mcxt.c):

/*
 * MemoryContextStrdup
 *              Like strdup(), but allocate from the specified context
 */
char *
MemoryContextStrdup(MemoryContext context, const char *string)


As I recall your original problem, people were suggesting that
you make a longer-lived copy of some transiently-allocated
string.  Copying it into a different context would be the
way to do that, as I hope you now understand from the README
discussion, and this function is the easiest way to do that.

Or at least the second easiest; the very easiest is pstrdup,
which is just

char *
pstrdup(const char *in)
{
        return MemoryContextStrdup(CurrentMemoryContext, in);
}

but I don't remember whether the current context was a suitable
target for your use-case.

                        regards, tom lane

Re: CurrentMemoryContext and MemoryContextStrdup

From
Tom Lane
Date:
Yessica Brinkmann <yessica.brinkmann@gmail.com> writes:
> Now, as I understand it (I don't know if I'm right), what I would have to
> do would be this:
> 1. I save the CurrentMemoryContext, for example as follows:
> MemoryContext oldcontext = CurrentMemoryContext;
> 2. I make the call to SPI, which was what caused the context problem.
> 3. I copy my variable in a different context, for example as follows:
> MemoryContext newcontext;
> char * copy = MemoryContextStrdup (newcontext, data);
> 4. Then, at the end of my call to SPI, after SPI_finish () I would have in
> the copy variable, the copy of the data variable, to use it as I want.
> Is that so? I am correct at least to try to modify my program or is it
> totally something else what should I do?

IIRC, the real issue here is that SPI_connect creates and switches into
a temporary context that SPI_finish will destroy; and the string you want
is in that short-lived context.  So what you want is to copy it out of
that context, probably into the context that was current before you
call SPI_connect.  So what you want is to do this before calling
SPI_connect:

    MemoryContext outer_context = CurrentMemoryContext;

and then this, inside the SPI operation, will save your string safely:

    copy = MemoryContextStrdup(outer_context, data);

            regards, tom lane



Re: CurrentMemoryContext and MemoryContextStrdup

From
Yessica Brinkmann
Date:
I understand. Many thanks. I will try to modify my program to adapt it to this.
Best regards,
Yessica Brinkmann

El mar., 26 nov. 2019 a las 15:11, Tom Lane (<tgl@sss.pgh.pa.us>) escribió:
Yessica Brinkmann <yessica.brinkmann@gmail.com> writes:
> Now, as I understand it (I don't know if I'm right), what I would have to
> do would be this:
> 1. I save the CurrentMemoryContext, for example as follows:
> MemoryContext oldcontext = CurrentMemoryContext;
> 2. I make the call to SPI, which was what caused the context problem.
> 3. I copy my variable in a different context, for example as follows:
> MemoryContext newcontext;
> char * copy = MemoryContextStrdup (newcontext, data);
> 4. Then, at the end of my call to SPI, after SPI_finish () I would have in
> the copy variable, the copy of the data variable, to use it as I want.
> Is that so? I am correct at least to try to modify my program or is it
> totally something else what should I do?

IIRC, the real issue here is that SPI_connect creates and switches into
a temporary context that SPI_finish will destroy; and the string you want
is in that short-lived context.  So what you want is to copy it out of
that context, probably into the context that was current before you
call SPI_connect.  So what you want is to do this before calling
SPI_connect:

        MemoryContext outer_context = CurrentMemoryContext;

and then this, inside the SPI operation, will save your string safely:

        copy = MemoryContextStrdup(outer_context, data);

                        regards, tom lane