Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes 1220: rocksjni build fails on Windows due to variable-size array declaration #1223

Merged
merged 2 commits into from
Jul 22, 2016
Merged

fixes 1220: rocksjni build fails on Windows due to variable-size array declaration #1223

merged 2 commits into from
Jul 22, 2016

Conversation

clumsy
Copy link
Contributor

@clumsy clumsy commented Jul 20, 2016

using new keyword to create variable-size arrays in order to satisfy most of the compilers

…y declaration

using new keyword to create variable-size arrays in order to satisfy most of the compilers
@ghost ghost added the CLA Signed label Jul 20, 2016
@adamretter
Copy link
Collaborator

@clumsy If you allocate memory with new you need to delete it when you are finished with it; SetByteArrayRegion makes a copy.

@adamretter adamretter self-assigned this Jul 20, 2016
@ghost ghost added the CLA Signed label Jul 20, 2016
@clumsy
Copy link
Contributor Author

clumsy commented Jul 20, 2016

How is it different from the current approach in terms of deleting the memory?

@adamretter
Copy link
Collaborator

@clumsy The current approach is allocated on the stack, but with new you are allocating on the heap. The stack will be cleaned up when the variable goes out of scope, variables on the heap are never cleaned up automatically, and must always be cleaned up manually.

@ghost ghost added the CLA Signed label Jul 20, 2016
@clumsy
Copy link
Contributor Author

clumsy commented Jul 20, 2016

Ok, thanks for the clarification. In that case will a const variable holding the value help?

E.g.:

const int size = compressionLevels.size();
jbyte jbuf[size];

@adamretter
Copy link
Collaborator

@clumsy The above would be allocated on the heap yes, but I do not know if that fixes the issue you are addressing on Windows. If it does then that is the simplest solution.

If not, then you just need to add delete [] my-array-variable, before the return of your functions; where my-array-variable is the one that you previously new'd.

@ghost ghost added the CLA Signed label Jul 20, 2016
@clumsy
Copy link
Contributor Author

clumsy commented Jul 20, 2016

No other solution is working for Visual Studio 15 C++ compiler on Windows.
I'll amend the patch to include delete[].

@yuslepukhin
Copy link
Contributor

yuslepukhin commented Jul 20, 2016

@clumsy To do it right wrap it into std::unique_ptr<char[]> as delete in any form in C++ generally means a memory leak.

The other way of doing this is to do alloca() then no delete is necessary and the space is allocated as before on the stack. Search for alloca() in the code as I have seen this issue before.

@clumsy
Copy link
Contributor Author

clumsy commented Jul 21, 2016

Ok, found a solution for unique_ptr as suggested by @yuslepukhin:

ttl.cc:

...
if (s.ok()) {
    jsize resultsLen = 1 + len_cols; //db handle + column family handles
    std::unique_ptr<jlong[]> results = std::make_unique<jlong[]>(resultsLen);
    results[0] = reinterpret_cast<jlong>(db);
    for(int i = 1; i <= len_cols; i++) {
      results[i] = reinterpret_cast<jlong>(handles[i - 1]);
    }

    jlongArray jresults = env->NewLongArray(resultsLen);
    env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
    return jresults;
  }
...

options.cc:

...
jbyteArray rocksdb_compression_list_helper(JNIEnv* env,
    std::vector<rocksdb::CompressionType> compressionLevels) {
  std::unique_ptr<jbyte[]> jbuf = std::make_unique<jbyte[]>(compressionLevels.size());
  for (std::vector<rocksdb::CompressionType>::size_type i = 0;
        i != compressionLevels.size(); i++) {
      jbuf[i] = compressionLevels[i];
  }
  // insert in java array
  jbyteArray jcompressionLevels = env->NewByteArray(
      static_cast<jsize>(compressionLevels.size()));
  env->SetByteArrayRegion(jcompressionLevels, 0,
      static_cast<jsize>(compressionLevels.size()), jbuf.get());
  return jcompressionLevels;
}
...

rocksjni.cc:

...
if (s.ok()) {
    jsize resultsLen = 1 + len_cols; //db handle + column family handles
    std::unique_ptr<jlong[]> results = std::make_unique<jlong[]>(resultsLen);
    results[0] = reinterpret_cast<jlong>(db);
    for(int i = 1; i <= len_cols; i++) {
      results[i] = reinterpret_cast<jlong>(handles[i - 1]);
    }

    jlongArray jresults = env->NewLongArray(resultsLen);
    env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
    return jresults;
  }
...

Will update my patch shortly.

@ghost ghost added the CLA Signed label Jul 21, 2016
…y declaration

using unique_ptr keyword to create variable-size arrays in order to satisfy most of the compilers
@clumsy
Copy link
Contributor Author

clumsy commented Jul 22, 2016

Please check most recent commit.

@yhchiang
Copy link
Contributor

wrap it into std::unique_ptr<char[]> sounds good to me.

@yhchiang yhchiang merged commit 12767b3 into facebook:master Jul 22, 2016
@yhchiang
Copy link
Contributor

LGTM. Merged it.

@adamretter
Copy link
Collaborator

Closes #1220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants