Banfa 597 Posting Pro Featured Poster

Your problem is between lines 23 - 31. You get 3 numbers from the user but you only use 1 variable so everytime you overwrite the previous number that the user input. Then at line 31 you push a single value, the last onbe entered, onto the stack. This comment // PUSH NUMBERS ON STACK at line 30 is distinctly confusing because it is not what the code is doing at all.

You need to push the value onto the stack after each time the user enters it.

Banfa 597 Posting Pro Featured Poster

You're trying to declare the same object obj twice at lines 19 and 22.

Your use of Fileout as a global object is extremely bad practice and the sort of thing that leads to unmanageable spagetti code. make Fileout local to main and then pass a reference to it to SavingsAccount::display. If you make the parameter for SavingsAccount::display a ostream& then you can pass all sorts of streams to it, cout, ofstream ostringstream etc.

Banfa 597 Posting Pro Featured Poster

Problem 1: is at lines 45 and 48. You are passing pointers to objects that are on the stack but your class assumes that the objects are on the heap and treats the pointer accordingly. Calling delete on a pointer to a stack object is always going to fail.

In fact you could make your class safer by not passing a pointer in the constructor at all, if it needs to use a pointer internally that is fine, pass an int by value and have the constructor allocate the memory for it internally, that is keep all the memory management hidden inside the class. If in reality the code is using something a little more complex that an int then pass a const reference, leave the calling code resonsible for its memory and you class responsible for its internal memory. If the design requires that the pointer is passed in then use a smart pointer and let the pointer handle the memory deallocation.

Problem 2: You have no copy constructor. The posted code makes no use of it so it has shown up as a problem, however best practice is if you need an assignment operator then you need a copy constructor and vice versa as generally they do very similar operations.

Banfa 597 Posting Pro Featured Poster

@Nikolas9896

Firstly scanf does add '\0' to the end of strings it reads. If you have an implementation that doesn't it is non-conforming and you should get a new compiler.

Secondly (name+'\0') is not valid syntax; operator+ has no meaning for an array.

Banfa 597 Posting Pro Featured Poster

The problem in deleteEntry is that you just free the memory for an entry without updating any of the pointers in the list at line 24

void deleteEntry ()
{
   struct Node *curr = Head;
   char name [15], decide;
   int Decide;
   printf("Last Name To Delete\n");
   scanf("%s", &name);
   getchar ();
   while(curr != NULL)
      {
         if(strcmp(name,curr->lastName))
         {
              printf("First Name: %s\n", curr->firstName);
              printf("Last Name: %s\n", curr->lastName);
              printf("Phone Number: %s\n", curr->Number);
              printf("Is This The Person You Would Like To Delete ? <Y/N>\n");
              scanf("%c", &decide);
              getchar ();

              if(decide == 'y' || decide == 'Y')
              Decide = 1;

              if(Decide == 1)
                free(curr);
         }
         curr = curr->next;
      }
}

Worst having done this at line26 you then go on to reference the memory pointed to by curr that has just been deleted.

In a singly linked list of say 5 items; A, B, C, D, E

If you want to delete an item from the middle, C, then you have to update the next pointer in B to point to D. That means that when you find the item you want to delete you have to still have a pointer to the item before that.

You also have to have a special case for the head item because in that case you have to update the head pointer rather than a pointer in the data structure.

The pseudo code might look a little like

If Head != NULL
  If Delete HEAD Item
    deletePtr = Head
    Head = Head->Next
    free deletePtr
  Else
    current = Head …
Banfa 597 Posting Pro Featured Poster

Fantastic post Schol-R-LEA except that sockets are one of the few things you don't get through Windows.h you have to explicitly include WinSock2.h :p

Also with some rather inverted logic because Windows.h is soooo big it can slow down compilation times so there are several symbols you can #define so that you don't include all of it into your program.

While code written for the QT enviroment can nominally be recompiled for either Windows or Linux (and we do do that at my work) you can't just write it willy-nilly you do have to remember to write your code portably.

Banfa 597 Posting Pro Featured Poster

Works fine for me using mingw 4.5.2 which is a c99 compiler. The only thing I would say is that the third line of StrCpy

    int size_destination = StrLen( destination ); //     !!!! Every time zero

is dangerous because you have no guarantee at all that the destination pointer currently points to a valid string which means you could end up scanning all of physical memory until you find a '\0' or cause a program crash. Strictly it is undefined behaviour because you may end up accessing an object outside its bounds.

Banfa 597 Posting Pro Featured Poster

Line 11 argv[i] = malloc(sizeof(temp)); or the modified form argv[i] = malloc(sizeof(temp+1)); does not allocate enough memory.

temp is a char* and has a fixed size 4 bytes (or maybe 8 depending on platform) so these 2 lines respectively allocate either 4 or 5 bytes of data. You then strcpy what temp points to into the location pointed to by argv[i]. This is likely to be a larger copy than the allocated memory.

You need to allocate memory for what temp points to not temp itself, the easiest (if not most secure) way is to use strlen and add 1 for the terminator.

argv[i] = malloc(strlen(temp)+1);
Ancient Dragon commented: Right :) +14
Banfa 597 Posting Pro Featured Poster

Char "is a simbol" found in ASCII code.

Not really, ASCII is a way of encoding alaphbetic (and other) symbols as a number and defines numbers in the range 0 - 255. And a char is an integer data type.

All characters can be converted into numbers in range 0-255, that's why is char 1 byte in size (2 to the power of 8 = 256).

Even more wrong, not all characters (in the world) can be converted into a number in the range 0 - 255 which is why Unicode, UTF-8, UTF-16, UTF-32 (methods of encoding characters like ASCII is) and wchar_t (wide character type like char is the single character type) exist.

char and int are both integer types each have several properties unique to themselves

char
signedness: if a char is signed or unsigned is platform dependent. it is usual to consider char, signed char and unsigned char as 3 distint types. Where as int is always signed and synonymous with signed int

trap bits: a char may not have trap bits it's value is an exact representation of the memory that contains it. In addition in an array of char, or incrementing a char pointer the individual char values obtained are required to be contiguous in memory. Neither of these are true of any other integer type, they may contain trap bits and do not have to be absolutely contiguous in memory means that if you want an exact view of …

mike_2000_17 commented: Very complete! +14
Banfa 597 Posting Pro Featured Poster

USART and SPI generally do different things and both tend to be 3 wire connections (because they require a ground). 2 wire connections tend to be used on a single PCB and don't require a ground because it would be extrememly unusual for a single PCB to have more than 1 ground.

Your micro processor supports a two wire interface (which appears to be to be I2C in all but name) as a separate periferal device and all three of these perfierals are described on pages 120 - 185 of the datasheet for the atmega8 device.

They are not normally hard to use, you configure your peripheral device, TWI for example, you configure the microprocessors i/o ports to give the peripheral device access to some of the pins of the microprocessor and then generally you write and read data to/from the transmit and receive buffers of the peripheral device.

This is more or less the same for any microprocessor and is vertually always described in detail in the microprocessors datasheet.

Get the datasheet for your microprocessor and read it.

Banfa 597 Posting Pro Featured Poster

Understanding the problem is very import to this kind of problem because while you may have to brute force the final solution understanding the problem can help you reduce the complexity making that brute force attack easier.

For example in the problem of placing 8 chess queens on a chess board such that no queen can take any other queen recognising that because a chess board has 8 rows and columns there will need to be only 1 queen in any row or column and 1 queen in every row and column helps reduce the complexity of the problem.

In this case you can use the fact that a knight on a white square attacks only black squares and vice-versa to reduce your problem complexity.

Banfa 597 Posting Pro Featured Poster

At lines 21 and 35 you have used this construct (*a)++ where a is a char*. Think about what this does ...

Because of the * in (*a)++ you do not increament the pointer a but rather what it points to, a char. You almost certain meant to increment the pointer like this a++. Because of this as soon as the condition at line 20 is true, lines 20-21 form an infinite loop because if x == y then (x+1) == (y+1).

Banfa 597 Posting Pro Featured Poster

Remeber a file is just a stream (or an array if you like) of characters. There are no lines that is just how some programs present the data to you, the use a special character or character combination (newline '\n' or carridge return '\r' or a combination of the 2) to tell the program when it should start displaying data on the next line so the file you described
contains the data

Line I don't care about\nAlso a line I don't care about\nLine I care about and want to change\nOne more line I don't care about\nand just one more line

You can read characters from a file and you can write characters from a file but strictly you can't read and write lines. The is a getline function but it doesn't read lines it reads characters until it sees the special character that identifies a place where the data would be shifted to the next line if it were being displayed like that.

That means that if you want to relace a "line" then you have 2 options the first is find the location of the data you want to replace and overwrite it with exactly the same number of characters as the "line" originally had. That is you can not insert data into a file and you can not delete data from the middle of a file intrinsiclly. This obviously only works if the data you want to write is the same length as the data you want …

Banfa 597 Posting Pro Featured Poster

When you type in that letter at line 9 cin enters an error state because it can not complete the requested operation, input a number. Additionally the letter you typed is left in the input buffer.

This means that at line 25 cin is still in an error state because you have not cleared it so it automatically fails. If you did clear the error it would still not enter the loop because the letter is still in the input buffer and it would immediately fail again at the operation read a number and put cin back into an error state.

Just inputing a letter when your program is expecting a number is not a good way to indicate the end of data you need a better strategy for reading data from the using for example

  • Sentinal Value: the list is finished when the user inputs a specific sentinal value, 0 or -1 are common ones. Any other value gets put in the list
  • After each value has been input ask if there is another value
  • Before asking for any values ask the user how many values they wish to input
  • Read the input as text, if it is a string of digits convert to a number otherwise end the loop

There are probably other strategies those are just what I can think of off the top of my head.

Banfa 597 Posting Pro Featured Poster

What was i initialised to before the loop started? This should work

i=a.begin();
while(i!=a.end())
{
  cout<<*i;
  i++;
}
Banfa 597 Posting Pro Featured Poster

unsigned long long sum doesn't work because start is still an int.

Banfa 597 Posting Pro Featured Poster

I've always said in C you should not cast the return value of malloc (or calloc). That is because if you leave out stdlib.h C will happily let you call the function without a predeclaration (although many C compilers produce warnings for that now but people then have to take note of them) by just assuming it returns int.

If you using most modern 64 bit systems and you do that then

In the presence of a cast
1. C presumes malloc returns int and silently casts your 64 bit pointer to a 32 bit integer.
2. You then let it you know what you are doing with a cast and so it, again silently, casts your 32 bit integer back to a 64 bit pointer.
3. It assigns that value to your pointer and some time later when you try to use it things go very very wrong.

Without the cast
1. C presumes malloc returns int and silently casts your 64 bit pointer to a 32 bit integer.
2. That value is not cast so it tries to assign a 323 bit integer to a 64 bit pointer. This is not allowed without a cast so a compiler error is produced and you find and fix the error. (Hopefully not with a cast*)

Fantastic so that was my normal canned answer, I just checked it on mingw32 and it in fact gave the same 2 warnings in both the cast of casting and …

Banfa 597 Posting Pro Featured Poster

It is hard to tell without seeing the definitions of g_spEngineLog and BOOSTSP although I am guessing from the name that it is a smart pointer defined by the Boost library.

Assuming that g_spEngineLog is also a BOOSTSP and that BOOSTSP has the normal operation for a smart pointer (i.e. it reference counts and deallocates when there are no references) I don't really see what is happening either.

I would say it is time to break out the symbolic debugger and put a break point in the destructor so you can tell when your object is being destroyed.

Banfa 597 Posting Pro Featured Poster

Seems we tend to get most irrate at the things we know and therefore stand out most to us as being wrong. A friend of mine who had been a train driver used to get excptionally irrate at how TV/movie trains react to things on the line vis-a-vis

a) There is a person/car/helicopter on the line head of the train you are driving should you:

  1. Lean on the horn and keep going
  2. Apply the breaks and attempt to stop before you hit the obstacle

b) The train you are driving unfortunately has just hit a person/car/helicopter do you:

  1. Keep going or you will be late for your tea
  2. Stop call the emergancy services and start filling out the mile high stack of paper work that clearing up this mess is going to take

EDIT: Just to say that I actually had only read the first page before posting so someone may have already mentioned this in which case sorry :D

Banfa 597 Posting Pro Featured Poster

My best guess would be that 22.5 has an exact represenation as a double (and may be a float) and 22.7 doesn't. However that is not the point, you don't need to know why one works and the other doesn't you need to know that using == is a mistake.

Banfa 597 Posting Pro Featured Poster

A 64bit integer is the largest native type currently in C++. However you are not the first person to have this problem and the way round it is to use a big integer classes. Classes of this nature can normally hold any number of digits which they do by using a vector of smaller integers to hold the values.

If you want you could try writing one yourself, it is a quite interesting exercise but if you just want to get on with the coding then try looking at Boost or googling "C++ BigInt"

Banfa 597 Posting Pro Featured Poster

In int **d=&a[0]; d has type int** and a has type int*.

The question is if a has type int* what is the type of the expression &a[0]? This isn't to hard to determine because using the array index operator gets rid of a level of indirection so if a has type int* then a[0] has type int. Then, since & adds a level of indirection (i.e. takes the address of), if a[0] has type int then &a[0] has type int*.

So you are assigning an int* to an int** and that is wrong assignments should always be between variables of the same type (or at least between variables with a well defined implicit conversion).

Another way to think of this is that a[0] can be directly replaced by *a they both return the thing a points to. Subsituting that into &a[0] gives &*a the &* cancel, you dereference then take the address of, ending up where you start so &*a is the same as a and therefore int **d=&a[0]; is the same as int **d=a; which is not what I think you want.

Banfa 597 Posting Pro Featured Poster

This is because floating point types (float, double, long double) only hold an approximation to the value you think they hold because of the way the value is encoded into the available memory (normally 4 or 8 bytes). e.g. You assigned 22.7 to d but actually it holds that as 22.7000000000001 in memory.

This approximation self evidently true particularly for a float because it (normally) has the same amount of memory as a long but holds a vastly larger range of numbers. Also floating point constants by definition have type double so 22.7 has type double, to use a float constant you have to post fix an F 22.7F has type float.

So in your code you take a double constant (which is an approximation of 22.7), convert it to a float in the assignment to f and then promote it back to a double for the comparison to d which itself is an approximation of 22.7.

During all that approximation, converting and promoting it is not surprising that the 2 values end up not exactly the same. In fact what is more surprising is that in your first example they don't end up different.

The rule of thumb usually used in comparing floating point types is that == always returns false and != always returns true. Your first code example shows that is not absolutely always the case but it is pretty much always the case in any but the most trivial examples.

Given that you should never use …

Banfa 597 Posting Pro Featured Poster

Personally I would recomend the Comb Sort algorithm rather than bubble sort which tends to be more efficient in the average case than Bubble sort but isn't that much more complex.

I have used it on a microprocessor (PIC) implementation with limited flash and ram (the list being sorted took around 75% of the available ram).

Banfa 597 Posting Pro Featured Poster

Instead of collection[2].GetId() use collection.at(2).GetId() the difference between these 2 calls is that calling at throws an exception if the index is out of range where using [] just does something undefined.

Assuming the index is in range then it is not a problem with the containers but what they contain. The data in collections is blank, which implies the data in nodesmap is blank which implies it isn't being read correctly.

Make sure you check all possible error code/results you can. For example from map::insert.

Banfa 597 Posting Pro Featured Poster

Line 41 - 43 you output to the closed file newemployee instead of dir

Banfa 597 Posting Pro Featured Poster

I think you have a problem at lines 2 and 3

//
for(a;a<sum;a++) {
    if(zaide[a] > 0) {

The initial expression at line 2 a looks wrong, did you mean a=0? Otherwise a is just forever getting bigger and you have not shown where you initialise a.

Then at 3 I think you have another array bounds problem. Again you have not supplied enough information to be sure but sum is being incremented in a manor that suggests it is going up quite quickly and if you remove the line incrementing sum your code works. sum going up allows the value of a to go up which could break the bounds of zaide.

Also strangly at line 6 you increment the value of a just before incrementing the value of a in the loop third expression.

Stuugie commented: Bam, I think you nailed that and I wish I saw it. +5
Banfa 597 Posting Pro Featured Poster

1 from the section of my website that I call "Poetry (sort of)"

The velociraptor of C++,
was talking to a poet thus:
the poet spoke, with some remorse,
“It's hard to fit your name in verse.”
The raptor to the poet said
“No it's not 'cos my name's Fred.
I see your error, you're confusing,
class and instance, how amusing.”

Banfa 597 Posting Pro Featured Poster

Yes, which every thing you are going to make major has to be the outside loop, the equation doesn't need changing.

Think about how a 3 by 2 matrix is layed out in memory if O is the offset to the first cell the each cell has the memory location

O+0, O+1
O+2, O+3
O+4, O+5

The array operator [] takes care of the offset O you need to generate the addition so for row major you need to generate the sequence 0, 1, 2, 3, 4, 5 for column major you need to generate the sequence 0, 2, 4, 1, 3, 5.

Taking your first code sample using a row major equation i*2+j and column major equation j*3+i iterating i in the range 0-2 and for every value of i j in the range 0-1 those 2 equations give in order

i j i*2+j j*3+i
0 0   0     0
0 1   1     3
1 0   2     1
1 1   3     4
2 0   4     2
2 1   5     5

You can see you row major equation gives the wrong sequence. If you reverse the loops, so that J is the outer loop you get

j i i*2+j j*3+i
0 0   0     0
0 1   2     1
0 2   4     2
1 0   1     3
1 1   3     4
1 2   5     5

Which gives you the 2 sequences you want all be it that the equations are actually used the other way round.

Banfa 597 Posting Pro Featured Poster

You will be very stuck if you can only use standard libraries because communication with a COM port is not part of the standard library and you normally have to use some 3rd party platform library.

When sending AT commands you need to be very careful with you line endings because they have relevence to the AT command command set. End commands with a carridge return, don't use new lines at all. Get to the point where you can send an "AT" and get the "OK" echo'd back to you before you get into more complex commands. be aware that the "+++" command to bring you from on-line mode to off-line mode should not have anything following it (i.e. no carridge return or line feed). Anything following a "+++" cancels it. You must send the "+++" and wait for the modem to get back to you with an OK which may be several seconds.

Remember that modems have a number of things you can set that effect what they send back to you, echo, results mode (numerical or status or extended). The first command you should send should be to configure the modem to send results in the manor you are expecting and to switch off the echo.

Banfa 597 Posting Pro Featured Poster

This code appears to lack design additionally it appears to have C++ elements but you have posted it into the C forum.

If I was going to pick on 1 thing then I do not think the variable button_counter is doing you any favours. Counting the button presses is not a good way to run a menu. The correct way to run a menu is to kepp track of what menu item is on display and know what the action of every button press on the current menu should be. Included in this is not needing to know what the previous button press is.

For example If the Angle is displayed
* Up - takes you to co-ordinate
* Down - takes you to time
* Select - Takes you to the angle set menu (if you can set the angle)
* Left - dones nothing (or takes you up one menu level if that makes sense)
* Right - does nothing (or the same as select)

The point is that a menu is stateful on what is currently displayed, not what button presses have gone before.

Work out your menu heirarchy and how the buttons cause transitions between the menus, draw a menu state diagram. The program it.

A second thing read_lcd_buttons, is not as useful as it could be. It should return the current button that is depressed but it would also be useful if it returned how long it has been depressed …

Banfa 597 Posting Pro Featured Poster

What is your question, your code seems to do what is intended?

Banfa 597 Posting Pro Featured Poster

The question does not seem to preclude the use of a human processor so how about

#include <string>
#include <iostream>

int main()
{
  std::string text;
  std::string reversed;

  std::cout << "Please enter the string to reverse: " << std::flush;
  std::getline(std::cin, text);
  std::cout << std::endl;

  std::cout << "Please enter the reverse of \"" << text << "\": " << std::flush;
  std::getline(std::cin, reversed);
  std::cout << std::endl << std::endl;

  std::cout << "The reverse of \"" << text << "\" is \"" << reversed << "\"." << std::endl;

  return 0;
}

And let us not forget it does preclude any library so you could just std::reverse(text.begin(), text.end()); :D

rubberman commented: Great post Banfa! Nothing like leveraging stuff like the STL. +12
Banfa 597 Posting Pro Featured Poster

You take it in as a string and then parse it into its constituent parts and interpret it.

std::string expression

std::getline(cin, expression);

// Parse string here
Banfa 597 Posting Pro Featured Poster

This is slightly stretching my, now 10 year out of date, recolection of WIN API programming but ...

I do not think GetStdHandle is likely to do what you want (with the caveat that of course I have no idea what you want so maybe it does) since it returns the standard handle for the current process but you want to set the stand output handle of your created process.

I seem to remember doing this by creating a pipe (CreatePipe) before creating the process and setting this as the std out handle in the STARTUPINFO structure passed to the process. Then you can read (and parse) the started applications output from the pipe.

Banfa 597 Posting Pro Featured Poster

Well you code compiles and links for me with exactly the commands you have given with the sole addition of #includes of cstdio and cstdlib to the top of your source files.

Also note that the array subscription operator has a higher preceedence than pointer indirection * so *A[j+i*N] is interpreted as as *(A[j+i*N]) which causes your program to exhibit undefined behaviour because I suspect you actually intended (*A)[j+i*N], which you can achieve by typing exactly that.

Banfa 597 Posting Pro Featured Poster

If you want to run a command in a command prompt you need to use the /c or /k switches before the command line, i.e. "C:\Windows\System32\cmd.exe /c ping google.co.uk"

Try cmd /? at a command prompt

Banfa 597 Posting Pro Featured Poster

So was I the only person for who DaniWeb was offline between 10am - 12noon UTC?

Or have I missed a downtime notice somewhere?

Banfa 597 Posting Pro Featured Poster

The actual code causing the problem is in line 84 - 90 of your code. Note that the solutions suggested so far would fix this because they would force you to fix this code.

In these lines you get the students scores and store then in the vector of the student class declared in main. Since you never clear this vector the second time around (i.e. for the second student) you are adding more marks to the same vector before storing it in a new student class instance. Ultimately the vector used to store scores in this loop can be local to the code and does not need to be stored in any class instance, it is transfered to a class instance at line 94.

Banfa 597 Posting Pro Featured Poster

It should be noted that for finding primes between in the range 1 - 100 any of the sieves are overkill of a high order.

since 1 is prime

Actually most university level matamaticians no longer think of 1 as prime, it is just a (very) special case. As far as I can tell this is because they had too many theorys/laws that went "for all primes, except 1, X is true" so they changed their minds about 1 being prime.

for (int i=2; i<=number/2; i++)

Very un-optimised, to start with if you test 2 independantly initially then you can skip testing all the other prime numbers (including ddanbe's suggested optimisation)

if ((number % 2) == 0) return false;
int sq = sqrt(number)
for (int i=3; i<=sq; i++)

You can take this further and apply a similar optimisation for multiples of 3 noting that every 3rd odd number is a multiple of 3

if ((number % 2) == 0) return false;
if ((number % 3) == 0) return false;
int sq = sqrt(number)
int step = 4;
for (int i=5; i<=sq; i+=step)
{
    step = 6 - step;
}

ddanbe optimisation reduces the number of check steps by a factor of 2 / sqrt(n) my optimisation further reduces it by approximately a factor of 1/3 resulting in checking each number for primeality against approximately 2 / 3.sqrt(n) less other values. If you were looking for primes in the range 1 - 1000 …

Banfa 597 Posting Pro Featured Poster

Yeah, you Europeans get the warm ocean current smashing on your coasts, while we get it on its way back from Greenland!

Yes and it's that warm ocean current and the jet stream that means that currently a flood warning map for the UK looks like this

3a352d43ba69bb3f3cf7f006e1743b69

And of course being British we never actually expected bad weather to be an issue for us and were rather caught on the hop.

I of course write this as one of the lucky people not currently having to deal with any flood water.

Banfa 597 Posting Pro Featured Poster

It is not cast to a float type because it is not a float type, since the type of p is char* the type of *p is char. This is an integer type and in the absence of a prototype indicating what type the parameter should be (which printf doesn't give because it accepts parameters of any type) this is then promoted using C rules about automatic promotion which basically means it gets promoted to an int.

Remember that the compiler does not store the type of the thing used originally to get the address stored in p so although you know that p points to a memory location that contains a float the compiler does not.

Banfa 597 Posting Pro Featured Poster

There are a couple of negative implications.

Firstly if you compile and run a program on 1 machine that writes a structure directly to a file in binary form using something like fwrite and reads it using fread and then you try and compile and run the same programme on a different machine and use the file created on the first machine the second machine may not read it correctly because the different machines may have inserted different padding in different places and may, ultimately have different sizes for the structure.

The second issue is one of memory wastage. Obviously any padding in your structure is not used for anything, it is unused and unusable (unless you are doing something very very suspect with pointers). How you write your structure, the order in which you place the members can effect the amount of padding in the structure, OK only by a few bytes (probably) but if you then have an array of those structures that wastage is multiplied. Now this wastage may be meanless on todays multi-gigabyte memory machines but it can easily be significant on microprocessors with much smaller memory. I have had to deal with this very problem when an array of poorly written structures was using more memory than needed on a platform that was running low on memory. My re-ordering the members of the structure (and replacing a few ints being used as booleans with a bit mapped int) I was able to save 20 bytes …

ddanbe commented: Great! +15
Ancient Dragon commented: good post :) +14
Banfa 597 Posting Pro Featured Poster

You have 2 problems and 1 unecessary variable.

The unecessary variable is being because the one place you use it, line 30, you could simply use index+1. U think this is better because it ties everything together through the single variable and properly maintains the relationship that element n in source array is copied to element n+1 in destination array as required in the question.

The first problem is a minor one, you never set the value of element 0 in the final array to 0 as the question requires.

The second problem is the real kicker, at line 33 you delete the array you have just created, that means that at line 34 you return an invalid pointer which in main you then try an dereference. This function is designed to allocate and return a new array so it should allocate data and not deleted it. The calling function, main, should store the returned pointer and then when it has finished with the new array it should delete it.

This remebering whose job it is to delete data is really an old C anacronism and is what classes, at least partially, help to get rid of. In production code you would expect a function like this to use a vector<> or array<> and have no need to track whose job it was to delete the array.

Banfa 597 Posting Pro Featured Poster

The (char *) is the cast command it tells the compiler what cawst you wish to make, in this case float* to char*. Note that casts of this type are not necessarily safe although I have seen such casts reasonbly often.

The at line 7 you tell printf you are passing it a parameter with type double with %f but what you actually pass is a variable of type char which is then automatically converted to int. This int has the value of the first byte in the memory that was being used to store the float. There is also a chance, depending on your Platform/OS, that the int is only 4 bytes long where as printf will be expecting a double of 8 bytes long so printf may well be reading more data off the stack than you put onto it which would be undefined behaviour.

The type specified by your printf format string (%f) must match the type actually passed to printf following the format string, many modern compilers parse the format string and emit warnings if they do not. For example mingw emits this message for line 7

test.c:7:5: warning: format '%f' expects type 'double', but argument 2 has type 'int'

Looking at memory

c contains the following 4 bytes (in hex on my system)
69 00 20 41

&c == p == 0x0028FF08 (When I ran it on my system this could be anything really)

Since p is a char* then *p is the first …

Banfa 597 Posting Pro Featured Poster

Personally I would ignore "(a Big-Oh answer will do)" and give an exact answer. You have the formula for fine after n days

fine = 2^(2^(n-1))

The second question is how many days will it take to for the fine to reach D (i.e. when fine = D) all you have to do is re-arrange your equation to find n in terms of fine (logarithms will help here)

ln(fine) = (2^n-1)ln(2)
ln(fine) / ln(2) = 2^(n-1)
ln(ln(fine) / ln(2)) = (n-1)ln(2)

Giving

n = (ln(ln(fine) / ln(2)) / ln(2)) + 1

This is simpler to read if written in terms of log to base 2

n = log2(log2(fine)) + 1

If you really want your big O notation look at your original formula and notice you are using an exponential of an exponential of days so O(e ^ e ^ x), remembering that Big O notation is an indication of how quickly something gets big.

Banfa 597 Posting Pro Featured Poster

An arry variable does not "point" at anything, it is an array with assigned memory and the properties of an array. On of the properties of an array is that when its symbol is used without an index it decays to a pointer to the first item in the array. Another property of arrays is that you can't pass arrays by value, that is you can not pass an array to any function, you can only pass a pointer to the first item in the array (what is most commonly done along with the size of the array) or a pointer to the array itself.

void fn1(char *p)
{
  printf("fn1: %d %d\n", sizeof(p), sizeof(*p));
}

void fn2(char p[])
{
  printf("fn2: %d %d\n", sizeof(p), sizeof(*p));
}

void fn3(char p[5])
{
  printf("fn3: %d %d\n", sizeof(p), sizeof(*p));
}

void fn4(char (*p)[5])
{
  printf("fn5: %d %d\n", sizeof(p), sizeof(*p));
}

In fn1, fn2 and fn3 p has type char* because it is just a char pointer and the values printed are 4(because I am using a 32 bit system) and 1. in fn4 p has type char (*)[5] and sizeof p is 4 still, but sizeof *p is now 5 because p points to an array.

The point is that in a function parameter using [] instead of * means nothing to the compiler although programmers sometimes use the [] notation to indicate the function is expecting an array rather than a pointer to a single thing. Also note that there is no …

Banfa 597 Posting Pro Featured Poster

Think about what you are doing, inputing a 1 x 5 array of strings.

The first question is is that what you really meant because an array index with a size of 1 is quite odd and rarely used? For example this char i2DArray[1][5]; and this char i2DArray[5]; allocate exactly the same amount of data, 5 char. So were you trying for an array of 5 names or a matrix 1 x 5 also, as it happens, containing 5 names?

If the answer is an array of 5 names then what is a name? it's a string and what is a string? it's an array of char. Assuming that we can set a maximum size for a string containing a name, to say 50 characters, we could define a type for a name string

typedef char namestring[50];

If we want an array of those then it would look something like

namestring i2DArray[5];

This is a 2d array because namestring is an array, we can combine these to produce the array without using a typedef, subsitute i2DArray[5] into the typedef line in place of namestring and remove the typedef giving

char i2DArray[5][50];

If you actually wanted a matrix 1 x 5 of names the same argument applies and you would end up with

// 2 dimensional array of strings
namestring i2DArray[1][5];

// substitute i2DArray[1][5] into namestring typedef
char i2DArray[1][5][50];

a dimension for each dimension of the matrix plus one for the actual size …

Ancient Dragon commented: Excellent :) +14
Banfa 597 Posting Pro Featured Poster

Does it work? It prints "Inside A!!!" but does it print a number on the next line? If not then your program silently crashed.

It can get into A::func and print the first line (which is what my windows implementation does before reporting a crash at the next line) because up to that point it has not had to dereference this. It is only at line 13 when trying to access _dmember that it deferences this which is NULL and crashes.

This is all undefined behaviour so in theory it could run and print out you age (don't ask me how it got your age, the behaviour is undefined remember, it can do anything, perhaps it dialed into some government agency hacked their computers and got a copy of your birth certificate). The import thing to remember here is always avoid undefined behaviour, it's bad and it doesn't necessarily show up in testing, only after it has been deployed for 2 months.

Banfa 597 Posting Pro Featured Poster

It is not at all clear what you are trying to achieve, however strings is an array of pointer to char (char *) so strings[i] (or any other index) has type char *, it is a pointer.

I have no idea why you would then cast to integer as testing a pointer against 0 is completely valid; check pointer is not NULL if(strings[i] != 0), it would be slightly more normal to use NULL if(strings[i] != NULL) (also note existance of nullptr symbol in C++11).

Casting a pointer to int is dangerous because you do not know that for any system the number of bits in an int is the same as the number of bits in a pointer and if they aren't you will (normall since if this is the case pointers are normally longer) truncate the pointer value.

And this is particular issue if you cast the output of malloc when not in the presence of a predeclaration of malloc since the compiler then assumes it returns int which is why you shouldn't cast the output of malloc in C.