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
}
paperduck
  • 1,175
  • 1
  • 16
  • 26
  • 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. – Lundin Feb 05 '14 at 14:30
  • Why the C++ tag? Looks like plain c. – TNA Feb 05 '14 at 14:31
  • Just for information "sizeof(char)" is _by definition_ 1. – jcoder Feb 05 '14 at 14:32
  • 3
    @TNA std::cout is C++. – Lundin Feb 05 '14 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. – Shlomi Hassid May 18 '22 at 05:10

3 Answers3

8

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...

barak manos
  • 29,648
  • 10
  • 62
  • 114
  • just for fun ^^: `sizeof("hello")` <=> `strlen("hello") + 1` (avoid `strlen` call & need for `s` variable) => do `malloc(sizeof("hello"))` and `strcpy(c, "hello")` – Zuzu Corneliu Jan 05 '16 at 13:35
  • @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. – barak manos Jan 05 '16 at 13:58
  • 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 ;) – Zuzu Corneliu Jan 05 '16 at 14:27
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.

timrau
  • 22,578
  • 4
  • 51
  • 64
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;
}    
haccks
  • 104,019
  • 25
  • 176
  • 264