Trouble passing a pointer array to a function - c++

In a program I am currently working on I have a template function included in a separate .h file that reads in five columns of data from a .txt file. The data is passed to the main program and in this instance I only care about the array title "MISC_DATA". I am trying to determine the largest value in the array "MISC_DATA" and have written another function that the data has to be passed to, in order to determine this. However, the compiler is telling me that it does not recognize the function call "Maximum_Value". I am pretty sure that it is having problems with the variable MISC_DATA included in the routine call and not the function itself. Either it does not recognize MISC_DATA as an array or I have the syntax wrong. I'm only including the important snippets of code to make it more readable. The Read_Five_Columns functions works fine, it is the function "Maximum_Value", which is not being recognized by the compiler because of how the pointer array MISC_DATA is written in the main program. For clarification the variable MISC_DATA in the function call is a float which contains the array and the variable "size_Mis" is an integer which contains the array size. Any thoughts would be appreciated.
int main(int argc, const char * argv[]) {
#include "Use_RNG.h"
#include "Read_Columnar_File.h"
#include <fstream>
#include <iostream>
std::vector<std::string> str3;
std::vector<int> str4;
std::vector<char> str5;
std::vector<int> str6;
unsigned long size_Mis;
std::vector<float> MISC_DATA; // Reads in Misc. spending data
char File1[8];
strcpy(File1, "Misc.txt");
Read_Five_Columns(File1,MISC_DATA,str3,str4,str5,str6);
str3.clear(); str4.clear(); str5.clear(); str6.clear();
size_Mis = MISC_DATA.size();
float value;
value = Maximum_Value(MISC_DATA,size_Mis);
end_time = clock();
std::cout << std::endl << "Total Time: " << (end_time-start_time)/CLOCKS_PER_SEC << std::endl;
return 0;
}
int Maximum_Value(float *array,int array_size)
{
float max = 0;
for(int i =10; i < array_size-1; i++)
{
if(array[i] > max) max = array[i];
}
return max;
}

There are four problems I see here.
int main(int argc, const char * argv[]) {
#include "Use_RNG.h"
#include "Read_Columnar_File.h"
#include <fstream>
#include <iostream>
All of this stuff is in the wrong order. You should not include system header files into function bodies, and typically you include standard library stuff before other stuff. Fix it to read like this:
#include <fstream>
#include <iostream>
#include "Use_RNG.h"
#include "Read_Columnar_File.h"
int main(int argc, const char * argv[]) {
Secondly, you don't declare Maximum_Value before you use it. You need to either move the definition of this function before the definition of main() or you need to add a prototype before main():
int Maximum_Value(float *array,int array_size);
int main(int argc, const char * argv[]) {
Then, you attempt to pass an std::vector<float> as a float* which does not work:
value = Maximum_Value(MISC_DATA,size_Mis);
However, because the storage for vectors is guaranteed to be contiguous and laid out like an array, you can pass a pointer to the first member safely:
value = Maximum_Value(&MISC_DATA[0],size_Mis);
Finally, you return int from Maximum_Value when you should probably be returning float.
If possible I would suggest leveraging std::max_element, which is part of the standard <algorithm> header:
// If you don't have C++11 then use std::vector<float>::iterator instead of auto.
auto max = std::max_element(MISC_DATA.begin(), MISC_DATA.end());
Now max is an iterator to the largest element, so *max would be the largest float itself.
(If the input range was empty, then max will be equal to MISC_DATA.end(), so the equivalent to your function would be value = max == MISC_DATA.end() ? 0f : *max;.)

Related

More effective way to load a std::queue<uint8_t*> with elements?

I am trying to find a more efficient method of loading variable length arrays of uint8_t bytes into a std::queue
The following code snippet is an attempt to reduce the actual code to something more usable as an example; so please forgive me if it's overly complex.
The code snippet works, with the exception of my inability to determine the actual length of each of the elements of the std::queue while they are still at the front of the queue. My question is, "Is there any way to push the pointer to the unsigned byte array into the queue without the intermediate step of creating a local array, copying the passed argument into it and then pushing the local pointer (See comments in code)?
#include <queue>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
using namespace std;
std::queue<uint8_t*> _q;
void routineSubroutine(uint8_t array_a[], int size_a)
{
/*
* Is there anyway to push the uint8 array_a into the queue (_q) without
* creating a new pointer to a byte array, copying the passed
* argument into it and the pushing it?
*/
uint8_t* a = new uint8_t[size_a];
memcpy((void*) a, (const void*) array_a, size_a);
_q.push(a);
}
int main(int argc, char** argv)
{
uint8_t myArray[512];
char cfa[] = {"I wish I was at Chick-Fil-A right now"};
memset((void*) myArray, 0x00, sizeof (myArray));
memcpy((void*) myArray, (const void*) cfa, strlen(cfa));
routineSubroutine(myArray, strlen(cfa));
char five[] = {"Five Guys will do in a pinch"};
memcpy((void*) myArray, (const void*) five, strlen(five));
routineSubroutine(myArray, strlen(five));
while (_q.size() > 0)
{
printf("Queue string value = %s\n", (char*) _q.front());
/*
* How do I go about determining the number of bytes in the uint8_t
* array, whose address is at the front of the queue?
*/
_q.pop();
}
return 0;
}
The code snippet works, with the exception of my inability to
determine the actual length of each of the elements of the std::queue
while they are still at the front of the queue
Use the proper container that knows its length/size and call the appropriate member function. A mere pointer doesn't do that.
Here is an example of your code rewritten to use std::vector:
#include <queue>
#include <string>
#include <vector>
#include <iostream>
std::queue<std::vector<uint8_t>> _q;
void routineSubroutine(const std::vector<uint8_t>& a)
{
_q.push(a);
}
int main(int argc, char** argv)
{
char cfa[] = {"I wish I was at Chick-Fil-A right now"};
routineSubroutine({std::begin(cfa), std::end(cfa)}); // creates a temp uint8_t vector
char five[] = {"Five Guys will do in a pinch"};
routineSubroutine({std::begin(five), std::end(five)}); // creates a temp uint8_t vector
while ( !_q.empty() )
{
// use the `write()` function to control the number of characters
std::cout.write(reinterpret_cast<const char *>(_q.front().data()), _q.front().size());
std::cout << "\n";
_q.pop();
}
return 0;
}
Output:
I wish I was at Chick-Fil-A right now
Five Guys will do in a pinch
Ultimately, I have full control over the type of queue I can use, while I have zero control over how the data is presented. Specifically the data is presented as a uint8_t* and size_t length. Thanks to #PaulMcKenie's example code I was able to come up with the following solution (which by the way is wicked fast):
std::queue<std::vector<uint8_t>> myQueue;
while(true)
{
// Pointer (myBuffer) and length (myLength) magically appear here
myQueue.push({myBuffer, (uint8_t*) (myBuffer + myLength)});
}
Problem solved.

C++ Passing a 2d c-string element into a function

What should be the proper way of doing this? Here's an example code of what I tried.
main
const int SIZE = 10;
char a[10][SIZE]; //assume this array already hold some character strings
fnc(a[2][SIZE]);
function
void fnc(char a[SIZE]){
cout << a;
}
I feel that I might be close, but I couldn't get it to work. Any help would be appreciated!
the function call in main should not be:
fnc(char a[2][SIZE]);
i am guessing you want to print the string at a[2]. Hence your function call should be:
fnc(a[2]);
Ok you want to pass an element from 2d char array to a function. So just pass two arguments to your function which indicate the position of your element.void fnc(int p1,int p2)
Your whole code will look like this.
const int SIZE = 10;
char a[10][SIZE];
fnc(2,0);
function
void fnc(int p1,int p2){
cout << a[p1][p2];
}
Hope this helps
You can pass 2D array like this:-
char array[10][10];
void passToFunc(int a[][10])
{
// ...
}
passToFunc(array);
Sorry for mis-interpretation:-
You can do it by :-
void passElement( char x )
{
//do something with x.
}
passElement( arr[1][1] ); //assume you want to pass 2nd element of 2nd 1-dimensional array.
Hope that helps :)
Your application never initializes the strings so there may be garbage being printed out. Here is an example that I did that works for me. Its a C++ app written using visual studio 2013.
Note that I initialized the strings to only 9 places in a 10 place array.
That is to account for the null terminator required for each string.
I hope this helps.
// TestApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string.h>
#include <iostream>
#include <windows.h>
using namespace std;
const int xSIZE = 10;
void fnc(char*);
int _tmain(int argc, _TCHAR* argv[])
{
char a[10][xSIZE];
strcpy(a[1], "012345678");
strcpy(a[2], "abcdefghi");
fnc(a[2]);
return 0;
}
void fnc(char a[])
{
cout << a<<endl;
}

int to string, char* itoa

trying to get ‘sval’ to contain the string “$1” – “$500” for array indexes 0-499. in the following code, however itoa is giving me strange strings in the code below:
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct data_t {
int ival;
char *sval;
} data_t;
void f1(data_t **d);
int main()
{
data_t *d;
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
f1(&d);
}
/* code for function f1 to fill in array begins */
void f1(data_t **d)
{
int i;
char str[5];
for (int i=0; i<500; i++)
{
(*d)[i].ival=i+1;
itoa (i,str,10);
(*d)[i].sval= str;
}
}
it also seems itoa has been depreciated, but that was what i got when i googled int to string
You don't need ltoa, cout should be just fine. Why do you need to keep the number and its string representation in the array? when you do cout << 10 you get "10" on the output, you don't need any conversions of your own
You, on the other hand, do ltoa without allocating any memory for the strings, which is not healthy as you have probably noticed. You use a local variable (the same, for all the 500 array members), which you try to access after you exit the function - a big no-no, its undefined behavior.
And:
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
No. Not only not needed - shouldn't be there at all! When in C++ - use new and delete, never malloc, that's a C function.

How to return a char array created in function?

I've been programming badly for quite a while and I only really just realised. I have previously created many functions that return character strings as char arrays (or at least pointers to them).
The other day someone pointed out that when my functions return the char arrays pointed to by my functions have gone out of scope and I'm essentially now pointing to a random bit of memory (A nasty dangling pointer).
I didn't really notice this for a while because the char arrays when outputted to the console didn't appear to be corrupt (probably because there wasn't time for that data to be overwritten). I did however notice this when I was returning a string buffer (char array) generated by reading the serial port which was frequently corrupt.
So, how best should I do it?
My bad code is as follows:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myBadFunction(){
char charArray[] = "Some string\n";
char* charPointer = charArray;
return charPointer;
}
int main(int argc, char** argv) {
cout << myBadFunction();
return 0;
}
I understand that I should perhaps allocate memory in the program before calling the function or create a global variable to put the returned string in, but if my called function is used by many different programs when how should it know the size of the buffer being passed into it in advance and when should this memory be deleted?
The following code also doesn't do what I want it to properly:
#include <cstdlib>
#include <iostream>
using namespace std;
void fillArray(char* charPointer){
char charArray[] = "Some string\n"; // Create string
charPointer = charArray; // Not correct, want to fill predefined array with created string
return;
}
int main(int argc, char** argv) {
char predefinedArray[50] = {0};
fillArray(predefinedArray);
cout << predefinedArray;
return 0;
}
I want to fill the array that the pointer parsed points to but this doesnt' happen in the code above.
Also, when should I use the new[] command to create my array? is it needed? and when should I call delete[] on it.
Many thanks for this, its obviously very fundamental but something I've been doing wrong for a while.
The simplest way would be to return a std::string, and if you needed access to the internal char array use std::string::c_str().
#include <iostream>
#include <string>
using namespace std;
string myGoodFunction(){
char charArray[] = "Some string\n";
return string(charArray);
}
int main(int argc, char** argv) {
cout << myGoodFunction();
return 0;
}
If you need to return something other than a char array, remember that pointers can be used as iterators. This allows you to encapsulate an array in a vector or a similar structure:
vector<int> returnInts() {
int someNums[] = { 1, 2, 3, 4 };
return vector<int>(someNums, someNums + 4);
}
You have two options for returning an array in C++. You can fill in pre-allocated memory (good), or allocate your own within the function and return it (bad). The reason that the first is preferred is because it re-enforces proper disposal of allocated memory.
A basic example would look like this:
void fillArray(char* buffer, int sz) {
char text[] = "hello there!";
if (sizeof(text)>sz) {
// overflow! Buffer is too small!
return;
}
for (int n=0;n<sizeof(text);n++) {
buffer[n] = text[n];
}
}
int main() {
char* buffer = new char[30]; // allocates a buffer of 30 bytes.
fillArray(buffer,30);
cout << buffer;
delete [] buffer;
}
/* note that it would be easier to use static memory in this example */
It isn't hard when you think about the problem.
Declare the array as "static" varible and return with its address.
This code works, but causes a warning :
#include <cstdlib>
#include <iostream>
using namespace std;
char* myBadFunction(){
static char charArray[] = "Some string\n"; // insert "static"
// char* charPointer = charArray;
return charArray; // charArray is a pointer to the static array
} // after returning static varibles stay safe
int main(int argc, char** argv) {
cout << myBadFunction();
return 0;
}
"Some string\n" is a string literal and will therefore exist for the lifetime of the program, so the following would be valid:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myGoodFunction(){
char* charPointer = "Some string\n";
return charPointer;
}
int main(int argc, char** argv) {
cout << myGoodFunction();
return 0;
}
Of course this is only useful if the function always returns the same string. If the returned string can vary (generally the case) then you can declare the char array in your function as static and return it's address (as has already been suggested).

change global variables in c++

Is there a way to define a global variable by user input?
Lets say I use
#include...
#define N 12
double array[N][N];
void main();...
But I would like the user to be able to choose what N is.
Do I have to have N as a local variable or is there a way around this(without macros)?
I've a pretty small program but with a lot of different variables that need the N value.
Alternatively,
is there a way I could send a group of variables into a function without having to explicitly write them out every time.
for example
myfunction(var1,var2,var3...)
and instead write something like
myfunction(Allvariables)
Thanks a lot for Your answers!
This is a great forum.
int* data;
int main()
{
int n;
// get n from the user.
data = new int[n];
// use data.
.
.
delete[] data;
}
or just forget pointers for ever and use vector!
std::vector<int> data;
data.push_back(55);
// just push_back data!
=======================================================================
EDIT ::
If you want to use Edouard A. way :)
#include <iostream>
#include <sstream>
#include <vector>
int main(int argc, char* argv[])
{
std::vector<double>::size_type dataSize = 0;
std::stringstream convertor(argv[1]);
{
if(argc > 1)
{
convertor >> dataSize;
if(convertor.fail() == true)
{
// do whatever you want here in case
// the user didn't input a number.
}
}
}
std::vector<double> data(dataSize);
// use the vector here.
return 0;
}
I prefere to use lexical_cast in this case, but I am not sure if you have Boost.
#include <iostream>
#include <vector>
#include <boost/lexical_cast.hpp>
int main(int argc, char* argv[])
{
typedef std::vector<double>::size_type vectorSize;
if(argc < 2)
{
// err! The user didn't input anything.
}
vectorSize dataSize = boost::lexical_cast<vectorSize>(argv[1]);
std::vector<double> data(dataSize);
// use the vector here.
return 0;
}
1/ Yes but you need dynamic memory allocation. The program parameters are passed as argc and argv to the main function
int main(int argc, char **argv)
argc is the number of parameters
argv is the array of null terminated strings representing these arguments
argv[0] is the program itself.
2/You can either use variadic function va_start & the like, or functions overriding, or group your data in a structure and pass that to the function
No, that can't be done this way. You need to use dynamic (runtime) memory allocation (new[]). To perform static (compile-time) memory allocation the compiler needs to know the memory block size at compile time.
I'm not really sure what you're trying to do with myFunction but it sounds like you want to look at either creating a struct or pass a std::vector
Make a class (or struct) AllVariables and pass that in.
You don't say whether you want N defined at run time or compile time. If you want it defined at compile time, you can define N as a compiler command line arguement.