LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-11-2020, 12:15 PM   #1
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311
Blog Entries: 2

Rep: Reputation: 16
Question error: redefinition of


I am trying to make a short mwe of realloc, more specifically how it can be used to expand integer arrays. Unfortunately due to the error:
Code:
a@a-TP-X200:/media/a/LG/AC/Learn/Programming/C/arrays$ clang -g -std=c99 -Wall -Wvla -Werror -fsanitize=address,undefined realloc_appendElements_func4.c 
In file included from realloc_appendElements_func4.c:5:
./verif_HeapMemRemains.h:2:7: error: redefinition of 'verif_HeapMemRemains'
        void verif_HeapMemRemains(int * buffer)
             ^
./verif_HeapMemRemains.h:2:7: note: previous definition is here
        void verif_HeapMemRemains(int * buffer)
             ^
1 error generated.
I prefer header files because:
Organization:
For future programs that use same/similar functions, I can look up past programs WAY QUICKER than pondering for hour after hour on remembering that I put the function for scanning in an integer Array in a program designed to demonstrate how to use 'remalloc'" or a program designed to track how many segments in a millipede's body with age or whatever.
and don't care whether it is reusable or not.

My program:
realloc_appendElements_func4.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include "printInt.h"
#include "expandArrThenVerif_int.h"
#include "verif_HeapMemRemains.h"
#include "scanIntArr.h"

//PURPOSE
//	First allocate enough for just a few first numbers.  Then to demonstrate "realloc"'s ability to resize an already existing array take in more numbers to add to the new space.

//Main Program
	int main (int argc, char** argv)
	{
		int * buffer;

		//1ST ARRAY
			int currentSize = 0;
			int increaseSize = 3;
			int firstElemOfNewAnnex = currentSize;
			currentSize += increaseSize;

			//Integer Array 1:  Allocate enough memory for 10 integers
				buffer = (int *) malloc (currentSize*sizeof(int));

			//VERIFY NEW MEMORY SUCCESSFULLY ALLOCATED
				verif_HeapMemRemains(buffer);

			//Scan in new values for the buffer
				scanIntArr(buffer, firstElemOfNewAnnex, currentSize);

			//DEBUG
				printInt(buffer, currentSize);
			
			
		//Expand Array
			char decide;
			
		//User decides to append array
			printf("Add elements(Y) or quit(N)> ");

			while((decide = getchar()) != EOF)
			{
				//Get rid of ensuing line feed
					getchar();
					
				//Upon user input 'n' terminate loop
					if(decide == 'n' || decide == 'N')
					{
						break;
					}

				//Number of elements to add to current array
					printf("Enter quantity of elements to add to end of current array> ");
					
					//Verify scan function succeeded scanning Data
						if((scanf("%d", &increaseSize)) != 1)
						{
							perror("scanf didn't return \"1\"/n");
							//printf("%d/n", stdin);
							exit(EXIT_FAILURE);
						}
					
					////Get rid of ensuing line feed
						//getchar();

				//Record which element new space will begin on
						firstElemOfNewAnnex = currentSize;
						currentSize += increaseSize;

				//REALLOC CURRENT BUFFER, VERIFY HEAP HAD ENOUGH REMAINING MEM
					buffer = expandArrThenVerif_int(buffer, currentSize);

				//Scan in second set of values for the buffer
					scanIntArr(buffer, firstElemOfNewAnnex, currentSize);

				//DEBUG
					printInt(buffer, currentSize);

				//User decides to append array
					printf("Add elements(Y) or quit(N)> ");
			}

		free (buffer);

		return 0;
	}
verif_HeapMemRemains.h
Code:
//VERIFY NEW MEMORY SUCCESSFULLY ALLOCATED
void verif_HeapMemRemains(int * buffer)
{
	//Check if heap had enough memory to allocate above space (out of memory)
		if (buffer==NULL)
		{
			printf("Error allocating memory!");
			
			//Free the initial memory block.
				free (buffer);
				
			exit (EXIT_FAILURE);
		}
}
scanIntArr.h
Code:
//SCAN IN VALUES TO THE ARRAY
void scanIntArr(int * buffer, int s, int l)
{
	int i;

//Initialize "buffer's" values
	for(i = 0 + s; i < l; i++)
	{
		printf("Enter integer array's %d 's element> ", i);
		scanf("%d", &buffer[i]);
	}
}
expandArrThenVerif_int.h
Code:
#ifndef verif_HeapMemRemains
#include "verif_HeapMemRemains.h"
#endif

//REALLOC CURRENT BUFFER, VERIFY HEAP HAD ENOUGH REMAINING MEMORY
	int * expandArrThenVerif_int(int * buffer, int currentSize)
	{
		/*get more memory with realloc*/
			//Assign pointer to the newly allocated memory to current variable "buffer"
				buffer = (int*) realloc(buffer, (currentSize)*sizeof(int));
					//***

		//VERIFY NEW MEMORY SUCCESSFULLY ALLOCATED
			verif_HeapMemRemains(buffer);

		return(buffer);
	}
Notice how in expandArrThenVerif_int.h I've attempted to use a header file. Even though it is realitively easy to find a lot of tutorials on how to understand the "theory" of header files, I couldn't find any concrete real life examples. Any recommendations?

Optionally, before I moved the functions outside of the main program, the decide = getchar() clause fails (can see when running in GDB) and no way to terminate loop, but that is not the main question, and I can repost for website organization standards if venerable contributors think appropriate.

Last edited by andrew.comly; 06-11-2020 at 01:09 PM.
 
Old 06-12-2020, 12:43 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,872
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
You could use `static` (or `inline`) modifier with these functions.
Also `decide` should be `int` not `char`.

Last edited by NevemTeve; 06-12-2020 at 12:46 AM.
 
1 members found this post helpful.
Old 06-12-2020, 02:39 AM   #3
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,950

Rep: Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326Reputation: 7326
You included the same h file several times, that caused this error.

inline or static are both usable, additionally:
Code:
#ifndef verif_HeapMemRemains
#include "verif_HeapMemRemains.h"
#endif
this ifdef should be put into the included h file, not around the #include.

You might want to use a macro instead of a function.
 
3 members found this post helpful.
Old 06-12-2020, 09:58 AM   #4
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,910

Rep: Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026Reputation: 5026
A while back, when I and other regulars here were assisting JSB in learning C, we touched on alloc/realloc. I posted an example of implementing a dynamic array which I've since broken into separate C source files/headers.

It stores strings rather than ints, but it sounds the same as what you're investigating so I'll post it here on the off-chance you find it helpful.

I don't know whether it counts as a good example, but it's an example.

lines.h:
Code:
#ifndef LINES_H
#define LINES_H

struct Lines
{
    size_t count;
    size_t capacity;
    char **lineArray;
};

struct Lines *allocLines();
struct Lines *freeLines( struct Lines *lines );
char *addLine( struct Lines *lines, char *line );
void printLines( struct Lines *lines );

#endif
lines.c:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#include "lines.h"

#define LINES_ALLOC_INITIAL 4
#define LINES_ALLOC_INCREMENT 4

struct Lines *allocLines()
{
    struct Lines *new = malloc( sizeof (struct Lines) );
    if ( new )
    {
        new->count = 0;
        new->capacity = 0;
        new->lineArray = NULL;
    }
    return new;
}

struct Lines *freeLines( struct Lines *lines )
{
    for ( char **line = lines->lineArray ; *line != NULL ; line++ )
        free(*line);

    free(lines->lineArray);
    free(lines);
    
    return NULL;
}

char *addLine( struct Lines *lines, char *line )
{
    if ( !lines || !line )
        return NULL;

    if ( lines->count + 1 >= lines->capacity )
    {
        size_t newSize = ( lines->capacity > 0 ) ? lines->capacity + LINES_ALLOC_INCREMENT : LINES_ALLOC_INITIAL;
        
        void *m = realloc(lines->lineArray, newSize * sizeof lines->lineArray);
        if (m)
        {
            lines->capacity = newSize;
            lines->lineArray = m;
        } else {
            return NULL;
        }
    }
    
    char *s = strdup(line);
    if ( s )
    {
        lines->lineArray[lines->count++] = s;
        lines->lineArray[lines->count] = NULL;
    }

    return s;
}

void printLines( struct Lines *lines )
{
    for ( size_t i = 0 ; i < lines->count ; i++ )
        printf("line: %s\n", lines->lineArray[i]);

    return;
}

And an example program to use it.

realloc-example.c:
Code:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include "lines.h"

void BOOM( void )
{
    fprintf(stderr,"BOOM!\n");
    exit(EXIT_FAILURE);

    return;
}

char *stripNewline( char *string )
{
    if (string)
    {
        char *nl = strrchr(string, '\n');
        if ( nl )
            *nl = '\0';
    }
    return string;
}

int main( void )
{
    char *lineBuf = NULL;
    size_t bufSize = 0;

    struct Lines *my_lines = allocLines();
    if ( my_lines == NULL )
        BOOM();
        
    while ( getline(&lineBuf, &bufSize, stdin) != -1 )
        if ( errno || ! addLine(my_lines, stripNewline(lineBuf)) )
            BOOM();
    
    free(lineBuf);

    printLines(my_lines);
    
    my_lines = freeLines(my_lines);
    
    return EXIT_SUCCESS;
}
Makefile:
Code:
CFLAGS = -Wall -Wextra -O2

realloc-example: realloc-example.o lines.o

.PHONY: all clean distclean

all: clean realloc-example

clean:
	rm -f *.o

distclean: clean
	rm -f realloc-example *~ \#*


realloc-example.o: realloc-example.c lines.h
lines.o: lines.c lines.h
I believe that's a pretty typical example of how headers are used in C: usually one doesn't put code in headers, only declarations/macros.
 
1 members found this post helpful.
  


Reply

Tags
getchar(), header, include files, scanf



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LFS binutils compile gold/fileread.cc error (struct iovec redefinition) chizisch Linux From Scratch 0 07-30-2019 07:46 PM
Redefinition error within single libcpp file - Good practice advice? Ratamahatta Linux - Software 1 09-27-2017 06:53 AM
installing glib: error: redefinition of typedef 'GListStore' jensjorda Linux - Newbie 2 04-14-2015 02:57 PM
error: redefinition of `GLXFBConfigSGIX' kornerr Linux - General 6 07-09-2005 11:15 AM
Redefinition error when building 2.6.9 kernel with acpi asmund1 Linux - Laptop and Netbook 2 12-05-2004 02:18 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration