Eyong Kevin Enowanyo
Eyong Kevin Enowanyo

Reputation: 1032

How to check an empty array returned from a function in C++

I was asked to write a function that accepts a character array, a zero-based start position, and a length. It should return a character array containing length characters (len) starting with the start character of the input array

#include<iostream>
#include<vector>
#include<iterator> 

using namespace std;

char* lengthChar(char c[],int array_len, int start, int len)
{
    char* v = new char[len];
    if(start < 0 || len > array_len || (start + len - 1) >= array_len){
        return NULL;
    }
    if((start + len) == start) 
    {
        return v;
    }

    copy(&c[start], &c[len+start], &v[0]);

    return v;
}

My question is when I call my function as

char* r = lengthChar(t,3, 1, 0);

Normally based on my implementation, it should return a pointer pointing to an empty array. However, I can't seem to verify this. When I do if(!r[0]), it doesn't detect it. I even did

char s[] = {};
char* tt = &s[0];
if(r[0] == *tt)

Still nothing. The strange thing is when I cout the value of r[0], nothing is printed. So I don't know what actually is return. How do I verify that it is empty?

Upvotes: 0

Views: 1237

Answers (2)

beaverTheory
beaverTheory

Reputation: 11

There are a few things going on here. Firstly, I would replace that

if((start+len) == start)

with just

if(len == 0) // if(!len) works too

And also note that you don't need to take the address of an index, so

&c[start] is the same thing as c + start

I would read http://www.cplusplus.com/reference/algorithm/copy/ to make sure you understand that the value being passed is an iterator.

But secondly, your char* v = new char[len] statement is invoking undefined behavior. When you call

new char[len];

You're merely telling the compiler that you want to give space to a new character array. Remember that std::cout is a function. It is going to detect a char array as a c string. This means that the char array needs to be null terminated. If it's not, you are truly just invoking undefined behavior because you're reading memory on places that have been allocated but not initialized.

When you call

if(!r[0])

This doesn't really mean anything at all. r[0] is technically initialized, so it is not a nullptr, but it doesn't have any data in it so it is going to evaluate to true with undefined behavior.

Now, if you want to make this more concrete, I would fill the array with zeros

char* v = new char[len];
memset(v, 0, len);

Now your char is a truly "empty" array.

I think it's just a misunderstanding of what an "empty" array actually means.

Finally, don't listen to the guys who say just use std::vector. They're absolutely right, it's better practice, but it's better to understand how those classes work before you pull out the real power of the standard library. Just saying.

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180490

Don't use if(!r[0]) to check if NULL was returned. You want to compare directly to NULL using if(!r) or if(r == NULL). This will tell you if the string is empty. Doing if(!r[0]) when you return NULL is undefined behavior so you definitely want to make sure the address is valid before you try and access what it points to.


Another thing to note is that in the case that you return NULL, you function has a memory leak. You need to move char* v = new char[len]; to after you decide if you are going to return NULL. You could call delete [] v; in the if statement, but that makes the code more brittle.

Upvotes: 3

Related Questions