Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Freeing

...

memory

...

that

...

is

...

not

...

allocated

...

dynamically

...

can

...

lead

...

to

...

serious

...

errors.

...

The

...

specific

...

consequences

...

of

...

this

...

error

...

depends

...

on

...

the

...

compiler,

...

but

...

ranges

...

from

...

nothing

...

to

...

abnormal

...

program

...

termination.

...

Regardless

...

of

...

the

...

compiler,

...

avoid

...

calling

...

free()

...

on

...

non-dynamic

...

memory.

...

A

...

similar

...

situation

...

arises

...

when

...

realloc()

...

is

...

supplied

...

a

...

pointer

...

to

...

non-dynamically

...

allocated

...

memory.

...

The

...

realloc()

...

function

...

is

...

used

...

to

...

resize

...

a

...

block

...

of

...

dynamic

...

memory.

...

If

...

realloc()

...

is

...

supplied

...

a

...

pointer

...

to

...

memory

...

not

...

allocated

...

by

...

a

...

memory

...

allocation

...

function,

...

such

...

as{{malloc()}},

...

the

...

program

...

may

...

also

...

terminate

...

abnormally.

...

Non-compliant

...

Code

...

Example

...

1

...

The

...

following

...

piece

...

of

...

code

...

validates

...

the

...

number

...

of

...

command

...

line

...

arguemnts.

...

If

...

the

...

correct

...

number

...

of

...

commmand

...

line

...

arguements

...

have

...

been

...

specified,

...

memory

...

is

...

allocated

...

with

...

malloc()

...

and

...

referenced

...

by

...

str

...

.

...

Next,

...

the

...

second

...

command

...

line

...

argument

...

is

...

copied

...

into

...

str

...

for

...

further

...

processing.

...

Once

...

this

...

processing

...

is

...

complete,

...

str

...

is

...

freed.However,

...

if

...

the

...

incorrect

...

number

...

of

...

arguments

...

have

...

been

...

specified,

...

str

...

is

...

set

...

to

...

a

...

string

...

literal

...

and

...

printed.

...

Because

...

str

...

now

...

references

...

memory

...

that

...

was

...

not

...

dynamically

...

allocated,

...

an

...

error

...

will

...

occur

...

when

...

str

...

memory

...

is

...

freed.

{
Code Block
}
int main(int argc, char *argv[]) {
  char *str = NULL;
  if (argc == 2) {
    str = malloc(strlen(argv[1]));
    if (str == NULL) {
      /* Handle Allocation Error */
    }
    strcpy(str,argv[1]);
  }
  else {
    str = "usage: $>a.exe [string]";
    printf("%s\n", str);
  }
  /* ... */
  free(str);
  return 0;
}
{code}

h2. Compliant Solution 1

In the compliant solution, theprogram has been changed to eliminate the possibility of {{str}} referencing non-dynamic memory and when it 

Compliant Solution 1

In the compliant solution, theprogram has been changed to eliminate the possibility of str referencing non-dynamic memory and when it is supplied to free().

Code Block
is supplied to {{free()}}.
{code}
int main(int argc, char *argv[]) {
  char *str = NULL;
  if (argc == 2) {
    str = malloc(strlen(argv[1]));
    if (str == NULL) {
      /* Handle Allocation Error */
    }
    strcpy(str,argv[1]);
  }
  else {
    printf("usage: $>a.exe [string]\n");
    return 1;
  }
  /* ... */
  free(str);
  return 0;
}
{code}

h2. Non-compliant Code Example 2

This example attempts to resize the string referenced by {{buf}} to make enough room to append the string {{line}}. However, once in the function {{append()}}, there is no way to determine how {{buf}} was allocated. When {{realloc()}} is called on {{buf}}, since {{buf}} does not point to dynamic memory, an error may occur.
{code}
void append(char *buf, size_t count, size_t size) {
  char *line = " <- THIS IS A LINE";
  int line_len = strlen(line);

  if ((count + line_len) > size)
    buf = realloc(buf,count+line_len);
  strcat(buf,line);
}

h2. Compliant Solution 2

Correcting the above example is an exercise in documentation. Since realloc is used to resize the memory pointed to by buf, the function append has the precondition that buf must point to dynamically allocated memory.
{code}
/\* NOTE: buf must point to dynamically allocated memory \*/
void append(char \*buf, size_t count, size_t size)
{   char *line = " <- THIS IS A LINE";   int line_len = strlen(line);    if ((count + line_len) > size)      buf = realloc(buf,count+line_len);   strncat(buf,line); }
{code}

{code}

h2. Compliant Code Example 2A

Alternatively, the function append could be rewritten not to use {{realloc()}} to resize buf. This solution goes beyond the scope of this document, but is nonetheless viable and, depending on the context of the program, may be preferred.

----
[j1]This violates recommendation 1 (sort of)

h2 References