By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,147 Members | 1,483 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,147 IT Pros & Developers. It's quick & easy.

memory related concerns

P: n/a
Hi,

Everybody, i have a situation where i receive data in a buffer and i
read the buffer and store it in a linked list, one the problem is i can
receive any number of data... so i might run out of the memory, and the
utiltimate aim is to return the header of the linked list to the caller
of the function, so that they can process the list and do the concerned
thing.

ht list is like this

struct list
{
int date;
struct *list
};

so having seen this limitation, is there any way of work around,
where i still can return the header of the node to the caller and don't
run out of memory simultaneously.

Jun 22 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
sa*****@yahoo.co.in wrote:
Hi,

Everybody, i have a situation where i receive data in a buffer and i
read the buffer and store it in a linked list, one the problem is i can
receive any number of data... so i might run out of the memory, and the
utiltimate aim is to return the header of the linked list to the caller
of the function, so that they can process the list and do the concerned
thing.

ht list is like this

struct list
{
int date;
struct *list
};

so having seen this limitation, is there any way of work around,
where i still can return the header of the node to the caller and don't
run out of memory simultaneously.


Well, you could do lazy evaluation of the list. Read what you need
into the current node of the list. When the caller wants to process the
next node - call a function rather than just dereference node->next)
which read/generate and fills in the next link in the list and disposes
the current node (incorporate instructions in the node so it knows
where to start reading from when you're processing the next node.)

Eventually this might just be a seemingly awkward way of streaming
chunks of data though :-)

Jun 22 '06 #2

P: n/a
On 22 Jun 2006 00:54:10 -0700, sa*****@yahoo.co.in wrote:
Hi,

Everybody, i have a situation where i receive data in a buffer and i
read the buffer and store it in a linked list, one the problem is i can
receive any number of data... so i might run out of the memory, and the
utiltimate aim is to return the header of the linked list to the caller
of the function, so that they can process the list and do the concerned
thing.

ht list is like this

struct list
{
int date;
struct *list
};

so having seen this limitation, is there any way of work around,
where i still can return the header of the node to the caller and don't
run out of memory simultaneously.

Yes, assuming that your code compiles.

Return the header of the node and add an argument that specifies
whether you ran out of memory. It might look something like this:

struct list* my_function(int *out_of_memory_ptr)
{
/* implementation that sets *out_of_memory_ptr
and returns the header of the node */
}

--
jay
Jun 22 '06 #3

P: n/a
sa*****@yahoo.co.in wrote:

Hi,

Everybody, i have a situation where i receive data in a buffer and i
read the buffer and store it in a linked list, one the problem is i can
receive any number of data... so i might run out of the memory, and the
utiltimate aim is to return the header of the linked list to the caller
of the function, so that they can process the list and do the concerned
thing.

ht list is like this

struct list
{
int date;
struct *list
};

so having seen this limitation, is there any way of work around,
where i still can return the
header of the node to the caller and don't
run out of memory simultaneously.


When I build a list, I keep track of both ends,
the head and the tail.
You can use the tail value to indicate node allocation failure.

/* BEGIN line2string.c */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>

struct list_node {
struct list_node *next;
void *data;
};

int line2string(FILE *fp, char **line, size_t *size);
void list_free(struct list_node *node, void (*free_data)(void *));
void list_fprint(FILE *stream, struct list_node *node);
struct list_node *
allocate_string_node(struct list_node **head,
struct list_node *tail,
char *data);

int main(void)
{
struct list_node *head, *tail;
int rc;
char *buff_ptr;
size_t buff_size;
long unsigned line_count;

puts(
"\nThis program makes and prints a list of all the lines\n"
"of text entered from the standard input stream.\n"
"Just hit the Enter key to end,\n"
"or enter any line of characters to continue."
);
tail = head = NULL;
line_count = 0;
buff_size = 0;
buff_ptr = NULL;
rc = line2string(stdin, &buff_ptr, &buff_size);
while (rc > 1) {
++line_count;
tail = allocate_string_node(&head, tail, buff_ptr);
if (tail == NULL) {
break;
}
puts(
"\nJust hit the Enter key to end,\n"
"or enter any other line of characters to continue."
);
rc = line2string(stdin, &buff_ptr, &buff_size);
}
switch (rc) {
case EOF:
if (buff_ptr != NULL && strlen(buff_ptr) > 0) {
puts("rc equals EOF\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = allocate_string_node(&head, tail, buff_ptr);
}
break;
case 0:
puts("realloc returned a null pointer value");
if (buff_size > 1) {
puts("rc equals 0\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = allocate_string_node(&head, tail, buff_ptr);
}
break;
default:
break;
}
printf("%lu lines of text were entered.\n", line_count);
puts("They are:\n");
list_fprint(stdout, head);
list_free(head, free);
puts("\nThe list has been freed.\n");
if (line_count != 0 && tail == NULL) {
puts("Node allocation failed.");
puts("The last line enetered didnt't make it onto the list:");
puts(buff_ptr);
}
free(buff_ptr);
puts("\nThe line buffer has been freed.\n");
return 0;
}

int line2string(FILE *fp, char **line, size_t *size)
{
int rc;
void *p;
size_t count;

count = 0;
for (rc = getc(fp); rc != EOF; rc = getc(fp)) {
++count;
if (count + 2 > *size) {
p = realloc(*line, count + 2);
if (p == NULL) {
if (*size > count) {
(*line)[count] = '\0';
(*line)[count - 1] = (char)rc;
} else {
ungetc(rc, fp);
}
count = 0;
break;
}
*line = p;
*size = count + 2;
}
if (rc == '\n') {
(*line)[count - 1] = '\0';
break;
}
(*line)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count > INT_MAX ? INT_MAX : count;
} else {
if (*size > count) {
(*line)[count] = '\0';
}
}
return rc;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -> next;
free_data(node -> data);
free(node);
node = next_node;
}
}

void list_fprint(FILE *stream, struct list_node *node)
{
while (node != NULL) {
fputs(node -> data, stream);
putc('\n', stream);
node = node -> next;
}
}

struct list_node *
allocate_string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -> next = NULL;
node -> data = malloc(strlen(data) + 1);
if (node -> data != NULL) {
if (*head == NULL) {
*head = node;
} else {
tail -> next = node;
}
strcpy(node -> data, data);
} else {
free(node);
node = NULL;
}
}
return node;
}

/* END line2string.c */
--
pete
Jun 22 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.