4

I am writing a program that reads a value from an .ini file, then passes the value into a function that accepts a PCSTR (i.e. const char *). The function is getaddrinfo().

So, I want to write PCSTR ReadFromIni(). To return a constant string, I plan on allocating memory using malloc() and casting the memory to a constant string. I will be able to get the exact number of characters that were read from the .ini file.

Is that technique okay? I don't really know what else to do.

The following example runs fine in Visual Studio 2013, and prints out "hello" as desired.

const char * m()
{
    char * c = (char *)malloc(6 * sizeof(char));
    c = "hello";
    return (const char *)c;
}    

int main(int argc, char * argv[])
{
    const char * d = m();
    std::cout << d; // use PCSTR
}
5
  • It is a bad idea to write one program in two different programming languages at once. Pick one language. If your compiler is Visual Studio, then you should definitely settle for pure C++, because VS has horrible conformance to standard C. Commented Feb 5, 2014 at 14:30
  • Why the C++ tag? Looks like plain c. Commented Feb 5, 2014 at 14:31
  • Just for information "sizeof(char)" is by definition 1. Commented Feb 5, 2014 at 14:32
  • 3
    @TNA std::cout is C++. Commented Feb 5, 2014 at 14:33
  • @jcoder Old post - But worth to point that "sizeof(char) is by definition 1" - Is a matter of what you consider 1 - for most machines and most compiler implementations 1 byte = 1 char = 1 octet (8 bit). That said, there are machines which CHAR_BIT will be 16 bit. And in this case 1 byte = 1 char = 2 octet - So its safe to say a char may be more than 8 bits, or more than one octet, but it's always one byte (Exactly as you said) - This is true for C, C++ and even objective c - And its important to know especially when developing for cross plat embedded stuff. Commented May 18, 2022 at 5:10

3 Answers 3

9

The second line is "horribly" wrong:

char* c = (char*)malloc(6*sizeof(char));
// 'c' is set to point to a piece of allocated memory (typically located in the heap)
c = "hello";
// 'c' is set to point to a constant string (typically located in the code-section or in the data-section)

You are assigning variable c twice, so obviously, the first assignment has no meaning. It's like writing:

int i = 5;
i = 6;

On top of that, you "lose" the address of the allocated memory, so you will not be able to release it later.

You can change this function as follows:

char* m()
{
    const char* s = "hello";
    char* c = (char*)malloc(strlen(s)+1);
    strcpy(c,s);
    return c;
}

Keep in mind that whoever calls char* p = m(), will also have to call free(p) at some later point...

Sign up to request clarification or add additional context in comments.

3 Comments

just for fun ^^: sizeof("hello") <=> strlen("hello") + 1 (avoid strlen call & need for s variable) => do malloc(sizeof("hello")) and strcpy(c, "hello")
@Zuzel: OP obviously misunderstands some basic concepts in the language (at least at the time the question was posted). I wanted to stick to the original code as closely as possible, in order to pinpoint the errors and avoid further confusion. Thanks.
yep, I agree, my intention was not to ask for answer edit :) I usually like to be surprised by these kind of little 'tricks' (language details), the comment was destined to such curious readers ;)
2

One way is to return a local static pointer.

const char * m()
{
    static char * c = NULL;
    free(c);

    c = malloc(6 * sizeof(char));
    strcpy(c, "hello"); /* or fill in c by any other way */
    return c;
}    

This way, whenever the next time m() is called, c still points to the memory block allocated earlier. You could reallocate the memory on demand, fill in new content, and return the address.

Comments

1

NO. This is not OK. When you do

c = "hello";  

the memory allocated by malloc lost.
You can do as

const char * m()
{
    char * c = (char *)malloc(6 * sizeof(char));
    fgets(c, 6, stdin);
    return (const char *)c;
}    

2 Comments

What if I changed that line to: c = strcpy(c, "hello");
@sailingonward: No, c = "string" assigns the address of a read-only string to a pointer variable. The previous memory address assigned to c was lost

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.