Frequency array of c++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
int arr,i=0,frequancy,y,X,l;
int V[arr];
cout<<"Enter the size of an array: ";
cin>>arr;
cout<<"Enter all "<<arr<<" elements in array: ";
for(i=0;i<=arr-1;i++)
cin>>V[i];
int a[arr]={0};
cout<<"Frequency of all "<<arr<<" elements in array:"<<endl;
for(i=0;i<arr;i++)
{
int count=0;
if (a[i]!=1)
{
for (int j=0;j<arr;j++)
{
if(V[i]==V[j])
{
count++;
a[j]=1;
}
}
if (count>1||count==1)
{
cout<<V[i]<<" occurs "<<count<<" times "<<endl;
}
}
}
return 0;
}
//this is the answer
Enter the size of an array: 9
Enter all 9 elements in array: 1
1
2
3
1
5
3
12
1
Frequency of all 9 elements in array:
1 occurs 4 times
2 occurs 1 times
3 occurs 2 times
5 occurs 1 times
12 occurs 1 times
So there are a few questions that I don't understand that well and I need someone to explain what is going on with it, please.
I don't understand why we have to initialize this(int a[arr]={0}) to 0, I asked my prof about it be he said it has to be like that. which doesn't answer my question:'C.
I have a problem with the bottom part of the code, I kinda understand a bit but if someone can help me that would help a lot Thank you!!!!

int arr/*...*/;
int V[arr];
cin>>V[i];
This program is badly broken.
Problem 1: The size of an array variable must be a compile time constant in C++. arr is not a compile time constant value. Violating this rule makes the program ill-formed, which means that compilers aren't required to compile it. You should avoid this.
Solution: If you need an array whose size is determined at runtime, then you should allocate the array dynamically. Simplest way to achieve that is to use the std::vector template from the standard library.
Problem 2: The behaviour of a program that reads an indeterminate value is undefined. Undefined behaviour means that there are no guarantees about the behaviour of the program whatsoever. This is very bad and should be avoided.
arr has an indeterminate value when you use it. The behaviour of the program is undefined. I repeat: This is very bad.
C++ is not a "data-flow" language. You cannot simply use a variable and initialise it after the usage. The program won't automatically stop, create a thread and wait for the later initialisation to proceed further.
Solution: Initialise before use.
I don't understand why we have to initialize this(int a[arr]={0}) to 0
Later on in the program, the values of that array are read (a[i]!=1). If you don't initialise the values before using them, then the behaviour of the program is undefined. See the previous paragraph.
Presumably, the elements of the array are initialised to zero in order to avoid that undefined behaviour.
Note that it is redundant to initialise the first element of the array explicitly to zero, and value initialise the rest, because those achieve the same thing. Thus, a simpler way to achieve the same is to value initialise all of the elements by not providing an initialiser for any of them:
constexpr int arr = 42;
int a[arr] {};
I have a problem with the bottom part of the code
The first step to solve that problem is to figure out why you think that you have a problem, and what kind of problem it could be.

Related

How is static array expanding itself? [duplicate]

This question already has answers here:
Why is it that we can write outside of bounds in C?
(7 answers)
Is accessing a global array outside its bound undefined behavior?
(8 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 11 months ago.
I wrote a code for entering element and displaying the array at the same time. The code works but since char A[4] is static memory why does not it terminate/throw error after entering more than four elements? Code:
#include <iostream>
using namespace std;
void display(char arr[],int n)
{
for(int i=0; i<n; i++)
cout<<arr[i]<<" ";
return;
}
int main()
{
char A[4];
int i=0;
char c;
for(;;)
{
cout<<"Enter an element (enter p to end): ";
cin>>c;
if(c=='p')
break;
A[i]=c;
i++;
display(A,i);
system("clear");
}
return 0;
}
Writing outside of an array by using an index that is negative or too big is "undefined behavior" and that doesn't mean that the program will halt with an error.
Undefined behavior means that anything can happen and the most dangerous form this can take (and it happens often) is that nothing happens; i.e. the program seems to be "working" anyway.
However maybe that later, possibly one million instructions executed later, a perfectly good and valid section of code will behave in absurd ways.
The C++ language has been designed around the idea that performance is extremely important and that programmers make no mistakes; therefore the runtime doesn't waste time checking if array indexes are correct (what's the point if the programmers never use invalid ones? it's just a waste of time).
If you write outside of an array what normally happens is that you're overwriting other things in bad ways, possibly breaking complex data structures containing pointers or other indexes that later will trigger strange behaviors. This in turn will get more code to do even crazier things and finally, some code will do something that is so bad that even the OS (that doesn't know what the program wants to do) can tell the operation is nonsense (for example because you're trying to write outside the whole address space that was given to the process) and kills your program (segfault).
Inspecting where the segfault is coming from unfortunately will only reveal what was the last victim in which the code is correct but that was using a data structure that was corrupted by others, not the first offender.
Just don't make mistakes, ok? :-)
The code works but since char A[4] is static memory why does not it terminate/throw error after entering more than four elements?
The code has a bug. It will not work correctly until you fix the bug. It really is that simple.

Why is memset causing problem despite being used on built-in types? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am very new to C++ and was making a submission to this problem on Codeforces and suddenly found that using memset() was causing Wrong answer to one of the test cases.
Here is the test case:
Input:
4 4
3 3 3 5
Participant's output
NO
Jury's answer
YES
1 2 3 4
Checker comment
wrong answer Jury has the answer but the participant hasn't
Here is the code:
#include<iostream>
using namespace std;
int check_if_painted[5010][5010];
int input_array[5010];
int main(){
int n,k;
cin>>n>>k;
int occurence_count[n];//Keeps track of the total no. of occurences of an element in the input_array.
memset(occurence_count,0,sizeof(occurence_count));
/*
The following loop checks if the occurrence of a particular
element is not more than k. If the occurence>k the "NO" is printed and program ends.
*/
for (int i = 0; i < n; ++i)
{
cin>>input_array[i];
++occurence_count[input_array[i]];
if(occurence_count[input_array[i]]>k){
cout<<"NO";
return 0;
}
}
cout<<"YES\n";
/*
The following loop uses the array check_if_painted as a counter to check if the particular
occurrence of an element has been painted with a colour from 1 to k or not.
If some previous occurrence of this particular element has been painted with f%k+1,
then f is incremented until we encounter any value(of `f%k+1`) from 1 to k that hasn't been
used yet to colour and then we colour this element with that value by printing it.
*/
int f=0;//
/*
f is a global value which increments to a very large value but f%k+1 is used
to restrict it within the 1 to k limit(both inclusive). So, we are able to check
if any previous occurrence of the current element has already been coloured with the value f%k+1 or not.
which essentially is 1 to k.
*/
for(int i=0;i<n;++i){
while(check_if_painted[input_array[i]][f%k+1]>0){
++f;
}
cout<<f%k+1<<" ";
++check_if_painted[input_array[i]][f%k+1];
++f;
}
return 0;
}
But, when I tried the below code, It was accepted successfully.
#include<iostream>
using namespace std;
int check_if_painted[5010][5010];
int input_array[5010];
int occurence_count[5010];
int main(){
int n,k;
cin>>n>>k;
for (int i = 0; i < n; ++i)
{
cin>>input_array[i];
++occurence_count[input_array[i]];
if(occurence_count[input_array[i]]>k){
cout<<"NO";
return 0;
}
}
cout<<"YES\n";
int f=0;
for(int i=0;i<n;++i){
while(check_if_painted[input_array[i]][f%k+1]>0){
++f;
}
cout<<f%k+1<<" ";
++check_if_painted[input_array[i]][f%k+1];
++f;
}
return 0;
}
From this post on SO, I found that memset works well on built-in types. So, why is it causing the problem in my case when it has been used on an int array which is a default type.
Also, I've also read that std::fill() is better alternative and read in this post that memset is a dangerous function, then why is it still in use?
This doesn't have anything to do with memset. Your code is going outside the boundaries of your array, plain and simple.
In your input case you have n = 4 and k = 4, so occurrence_count is 4 elements long (its valid indexes go from 0 to 3 inclusive). Then, you do
cin>>input_array[i];
++occurence_count[input_array[i]];
Given that the last value is 4, you are ultimately doing ++occurence_count[4], which goes out of the boundaries of your array. This is undefined behavior, which in your case manifests as incrementing memory not belonging to that array, which most probably doesn't start to 0 and messes up the later check.
The problem is not seen in your second code snippet, as you make occurence_count 5010 elements big and zero-inizialized by default as it is a global variable.
Now, if you are going to count occurrences of array values, of course sizing the occurrences array to be as big as the number of elements is wrong - that's the count of numbers you are going to read (and it would be fine to size input_array), not the maximum value you can read. Given that the array element values are from 1 to 5000, the occurrences array must be either sized 5001 (keeping values as they are), or sized 5000 (decrementing the values you read by 1 to index such array).
(In general, be careful as all indexes in the problem text are 1 based, while indexes in C++ are 0 based; you risk off-by-one errors if you reason with the problem indexes and then use them as C indexes, unless you over-size arrays by one and ignore the 0-th element).
Finally, some extra remarks:
if you compile with enough warnings enabled or with a recent enough compiler, it'll rightly complain as memset is not defined or that it is being implicitly defined (with an incorrect prototype, BTW); you should #include <string.h> to use memset;
as #Nicol Bolas went to a great length to explain in his answer, you are using VLAs (variable length arrays) when declaring a local array with size known only at runtime (int occurence_count[n]).
VLAs aren't standard C++, so they aren't well specified, several compilers don't support them and, in general, are problematic in a number of ways (mostly, you shouldn't really allocate an unknown amount of data on the stack, which is generally small);
You should probably avoid them in favor of std::vector or, given that the problem provides you an upper limit of both colors and elements (5000), just static arrays.

Crashing Pointer Array C++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
Code::Blocks, Win7, C++
Hi, I'm creating an overview project for myself, and an integral part includes doing an Exchange Sort in descending order. I've created a simple trial run to test the concept.
Embarrassingly enough, I can't get past creating the array without the project crashing. This only happens when I create the array with pointers (My project's arrays are pointers, which is why I need this to work). The code compiles fine, but when I run it, I get a Window's notification that "ArrayTest.exe has stopped working"
When I print out each dereferenced value, I get:
"The original order: 1 13 5 7 2 "
When I print out each value's address, I get:
"The original order: 0x28ff08 0x28ffc4 0x760c8cd5 0x6aadab61 0xfffffffe "
The last address showed up when using an array length of 6, and crashes as well. Am I blind to a simple error in my code, or is this a hardware issue?
//filename ArrayTest
#include <iostream>
using namespace std;
int main()
{
int *j[5];
(*j)[0] = 1;
(*j)[1] = 13;
(*j)[2] = 5;
(*j)[3] = 7;
(*j)[4] = 2;
cout << "The original order: ";
for (int i = 0; i < 5; i++)
{
cout << (*j)[i] << " ";
}
return 0;
}
Consider int *j[5]; carefully. This is an array of pointers.
Those pointers are not pointing to memory that you own.
So the behaviour on dereferencing them is undefined.
Trivial fix: use int j[5]; instead, and j[0] = 1 etc.
When analysing code problems consider these numbers as approximating the probability of the error location:
99.0% - your code
0.9% - the standard library
0.09% - the compiler
0.009% - the operating system
0.001% - the hardware
If you want a pointer on array, you have to use this syntax
int array[5];
int (*j)[5] = &array;
(*j)[0] = 42;
So, firstly, the correct syntax is int j[5]; but that's C, not C++.
use std::array - actual C++ and with compile-time checking.
You're allocating an array of 5 pointers to int, not an array of 5 integers. Try to init the array like this: int j[5];
Your code writes your values 1, 13, 5, 7, 2 to the dereferenced pointers in your pointer array. Since they are uninitialized, they contain garbage and thus you're writing to random addresses in memory, which leads to the crash.

How could it get more memory than I wanted?(C++) [duplicate]

This question already has answers here:
Why doesn't my program crash when I write past the end of an array?
(9 answers)
Closed 8 years ago.
I wanted to take a 1 integer memory, but how this program can work?
Code:
#include<iostream>
using namespace std;
int main(){
int* k=new int[1];
for(int i=0;i<5;i++)
cin>>k[i];
for(int i=0;i<5;i++)
cout<<k[i]<<"\n";
delete[] k;
return 0;
}
Input:
999999
999998
999997
999996
999995
Output:
999999
999998
999997
999996
999995
You invoked undefined behavior by accessing memory you did not allocate. This works purely "by chance". Literally every behavior of you program would be legal, including the program ordering pizza, ...
This will probably work in practice most of the time because your OS will usually not just give you 4 Byte or something like this, but a whole page of memory (often 4kB) but to emphasize this: You can never rely on this behavior!
The way that a c++ program uses an array is that it the index that you want, multiplies it by the size of the element the array is made of, then adds it to the first memory location in the array. It just so happened that where you placed this in your program, going back an additional 4 elements didn't corrupt anything, so you were just fine. It doesn't actually care. However if you overwrite another variable, or a stack pointer, then you run into trouble. I wouldn't recommend doing this in practice, however, as the behavior can be undefined.

Getting Array from Another class C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am making a simple Lottery program - and am struggling with implementation. I have a class called 'Ticket Line' this class simply holds 6 numbers that the player is playing a lottery for.
What I want to do, is generate 6 randomly (got function for this already) and then store that in another class as values. To do this, I am using the following code:
class Draw
{
private:
int drawID;
TicketLine* DrawnNumbers;
bool drawn;
}
When a Draw is completed I want to generate the Random Numbers ( from the TicketLine class) and then for the Draw to be able to store those numbers into its Draw File.
How would I be able to access the functionality of the DrawnNumbers class - and store the results from the getTicketNumbers.getTicketLine()function.
int* getTicketNumbers(void) { return DrawnNumbers->getTicketLine();};
The program crashes the following code:
//int *ptr[6] = getTicketNumbers();
int *ptr[6] = getTicketNumbers();
for (int x = 0; x < 6; x++){
cout << ptr[x];
}
TicketLine class:
private:
int select[6]; //Array of Ticket Numbers.
int* getTicketLine(void) { return select; };
I am willing to offer a couple of virtual beers to the solution. I am as yet to find a good online pub - if you know of one then please do let me know :-)
Thanks,
Without knowing any more, this line:
int *ptr[6] = getTicketNumbers();
is very suspect.
Why? Well, we haven't seen the implementation of getTicketNumbers so we don't know if it's actually allocating memory for 6 and returning such an array.
Also, you are printing the values of pointers here:
for (int x = 0; x < 6; x++){
cout << ptr[x];
}
Where, if you intended to actually print the int values, you'd say something like this:
for (int x = 0; x < 6; x++){
cout << *(ptr[x]);
}
My guess is that you are either:
Going out of bounds of an array that was (not) allocated, or,
Modifying actual pointer values somewhere instead of the integers they point to (as indicated by your lack of dereferencing ptr[x] in your print statement)
Edit
With more information, it seems you probably meant to say this:
int *ptr = getTicketNumbers();
instead of this:
int *ptr[6] = getTicketNumbers();
You should probably be doing some sanity checks as well to make sure that select is actually filled before calling that function (maybe giving it a default value of {0,0,0,0,0,0} in the constructor)
DrawnNumbers doesn't appear to be pointing to anything yet. It's a pointer, but to what?
Also, be careful about returning arrays that way. If the object or stack frame that the array resides in goes away, you'll be left pointing to bad things.