5

I'm normally programming in c++, but are using some clibrary functions for my char*. Some of the manpages like for 'getline', says that input should be a malloced array.

Is it ok, to use 'new' instead?

I can see for my small sample that it works, but could this at some point result in some strange undefined behavior?

I know that a 'new' should match a 'delete', and a 'malloc' with a 'free'.

I'm also not using std::string. And this is intentional.

Thanks

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
monkeyking
  • 6,670
  • 24
  • 61
  • 81
  • No it is not OK. But if you are using C++ why not use std::getline()? – Martin York Dec 28 '09 at 04:36
  • 2
    Whenever you see something like this in documentation you need to dig deeper and figure out if they recommend a 'malloced' pointer because they are using C terminology or because the function is expected to call realloc() or free(). The highest voted answers below assume the former although I believe the function you're referring to has to do with the latter as Martin points out. It's not OK to pair malloc/free and new/delete incorrectly, so it's best to do additional research on the specific functions you're calling when this comes up. – Dan Olson Dec 28 '09 at 05:38

3 Answers3

13

The buffer passed to getline() MUST be malloced.

The reason is that getline() may call realloc() on the buffer if more space is required.

realloc() like free() should only be used with memory allocated by malloc(). This is because malloc() and new allocate memory from different storage areas:

See: What is the difference between new/delete and malloc/free?

Basically new uses "The "Free Store" while malloc uses "The Heap". Both of these areas are part of the "application Heap" (Though the standard does not actually require an application heap as that is an implementation detail). Though they are both on the "Application Heap" these areas need not overlap. Whether they do is a detail of the implementation.

The man page for getline():

Notice this line:

Alternatively, before calling getline(), *lineptr can contain a pointer to a malloc()-allocated buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc(), updating *lineptr and *n as necessary.

Community
  • 1
  • 1
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 2
    @Martin: you're pointing to a GCC-extension function "getline". I don't think it's too great to recommend using this non-portable function, especially to newbies – Eli Bendersky Dec 28 '09 at 04:53
  • 1
    @Eli: the question specifically mentions `getline`. – Pavel Minaev Dec 28 '09 at 05:27
  • @Eli: I would recommend against any C functions where there is a usable C++ alternative. But the question is specifically asking about the C getline() functionality. And when the documentation specifically mentions using malloc(ed) memory there is usually a very good reason to-do so. – Martin York Dec 28 '09 at 06:43
  • @Martin: Thanks a ton! I guess I have been so ignorant about this. :) – UltraInstinct Dec 28 '09 at 07:21
2

Yes, it's OK to use a pointer allocated with new when a "malloced" one is expected.

By the way, getline isn't ISO C. There's a getline in standard C++ library, but that one expects a std::string. For standard C file reading you should use fgets. The following works (simplified code assuming existence of infile and doesn't check fgets return value - which you probably should in real code):

// infile is some open FILE* object
int mylen = 100;
char* line = new char[mylen];
fgets(line, mylen, infile)

However, a mandatory disclaimer: it's much better to use std::string and getline if you're using C++.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • 1
    I know the original C standard came out of ANSI but that's a national body and ISO is now responsible for the standard. Please try to use "ISO C" if you can. – paxdiablo Dec 28 '09 at 04:07
  • 1
    @paxdiablo: fixed to "ISO C". using ANSI is just a habit from times past :-) – Eli Bendersky Dec 28 '09 at 04:13
  • 5
    It is not always ok to use new(ed) memory where malloc(ed) is expected. If it just uses the memory as raw memory fine. But if memory management routines are used on the pointers then you can not make this assumption. getline() may potentially call realloc() on the pointer passed. This is equivalent to calling free() on the pointer i.e. it is undefined behavior. – Martin York Dec 28 '09 at 04:36
  • @Martin: getline doesn't really accept a char* - do you mean another routine? fgets will not call realloc – Eli Bendersky Dec 28 '09 at 04:45
1

It is perfectly fine to have a 'new'ed array instead of 'malloc'ed array for the purpose.

The differences between the two are (to list some of them) :

  • new/delete call the constructor/destructor of the associated object unlike malloc/free. The latter can not perform initialisation/deinitialisation stuffs.
  • new returns a pointer of proper type but the pointer what malloc returns has to be typecasted (C++)
  • new/delete does not have realloc alternative unlike new/delete

These things are not going to make much of difference in your program; so as stated above, it is perfectly fine to go for 'new'

Your code will not fail, unless new or malloc fails, in which case, 'new' throws an exception, and malloc return a NULL pointer.

EDIT: For the purpose, the array must be 'malloc'ed. I guess I was wrong back then! Thanks Martin! :)

UltraInstinct
  • 43,308
  • 12
  • 81
  • 104