Skip to content

Memory leak #963

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

Open
NiekBeijloos opened this issue Mar 28, 2020 · 7 comments
Open

Memory leak #963

NiekBeijloos opened this issue Mar 28, 2020 · 7 comments

Comments

@NiekBeijloos
Copy link

NiekBeijloos commented Mar 28, 2020

Dear readers,

After running the BLE_client sketch for a while it crashes because of memory leak.
It is also visible with the following function Serial.println(ESP.getFreeHeap());.

Someone having the same issue according to the memory leaks within the BLE library?
Maybe a solution to these memory leaks?

Thank you in advance.

Yours sincerely,
Niek

@chegewara
Copy link
Collaborator

Hi,
There is few issues about memory leak on this repo and i believe there is no more leaks in library. If you find memory leak in BLE_client example then most likely its example code that is causing leak.

During investigating memory leak in BLEScan i found that leak cause was in my test code, not scan class itself. It was caused by using Task class from this repo wrong way.

Maybe if you can narrow down where you have memory leak i can investigate it.

@NiekBeijloos
Copy link
Author

NiekBeijloos commented Mar 28, 2020

Hi,
Thank you for your response. I am trying some own written code now, but still run in the same memory leak problems. My code:

#include <BLEDevice.h>

//uuid
static BLEUUID serviceUUID("ffeaa981-d01c-4e9f-9004-d8677158a914");
static BLEUUID charUUID("ffeaa981-d01c-4e9f-9004-d8677158a914");

//ble objects
BLEAdvertisedDevice* myAdvertiseDevice;
BLEAddress *Server_BLE_Address;
BLEScan* pBLEScan;
BLEClient*pMyClient;
BLERemoteService* pMyRemoteService;
BLERemoteCharacteristic* pMyRemoteCharacteristic;

//variables
char oldDevice[18];
char newDevice[18];
bool pherhiperalFound = false;
uint8_t number = 0;
long unsigned int startMillis = 0;

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    
    Server_BLE_Address = new BLEAddress(advertisedDevice.getAddress());
    strcpy(newDevice,Server_BLE_Address->toString().c_str());
    //Serial.printf("BLE Advertised Device found: %s \n", newDevice);
    //Serial.printf("Size of string: %i /n",strlen(Server_BLE_Address->toString().c_str()));
    
    if (advertisedDevice.isAdvertisingService(serviceUUID) && strncmp(newDevice, oldDevice,17) != 0) {
      pBLEScan->stop(); // stop scanning when the pheripheral is found
      //Serial.println("Stopped scanning");
      //Serial.printf(oldDevice);
      strcpy(oldDevice, newDevice); // copy new device in old device
      myAdvertiseDevice = new BLEAdvertisedDevice(advertisedDevice);
      pherhiperalFound = true;
      startMillis = millis(); // timer starts
    }
    else{
      pherhiperalFound = false; 
    }
  } 
};

void setup() {
  Serial.begin(115200);
  Serial.println("Scanning...");
  BLEDevice::init("OPERATOR"); // static function declaration 
  pBLEScan = BLEDevice::getScan(); // This is mainly the case for helper classes 
  //that contain public functions to do some repetitive and general work, but don't need to maintain any state between calls.
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan meaning Pheripheral sends response
  pBLEScan->setInterval(100); // interval in ms between scanning
  pBLEScan->setWindow(99);  // less or equal setInterval value
  pBLEScan->start(5, false); // scan for 5 seconds then stop 
}

void loop() {
   
  if(pherhiperalFound){
    pMyClient = BLEDevice::createClient();
    pMyClient-> connect(myAdvertiseDevice->getAddress());
    Serial.println("Connected...");
    pMyRemoteService = pMyClient->getService(serviceUUID);
    pMyRemoteCharacteristic = pMyRemoteService->getCharacteristic(charUUID);
    uint8_t number = pMyRemoteCharacteristic->readUInt8(); 
    Serial.println(number);
    delay(1000);
    pMyClient->disconnect();
    Serial.println("BLE Disconnected"); 
    pherhiperalFound = false;
  }
  else{
    pBLEScan->clearResults();
    pBLEScan->start(5,false); // false so we don't continue with the same device and clear the memory
    if(millis()- startMillis >= 1000){
      strcpy(oldDevice,"");     
    }  
  }
  Serial.println(ESP.getFreeHeap());
  delay(500);
} 

Hope you could help, thanks!

Niek

@chegewara
Copy link
Collaborator

This will create new instance of class, but you never delete it:
myAdvertiseDevice = new BLEAdvertisedDevice(advertisedDevice);
The same situation is here:
Server_BLE_Address = new BLEAddress(advertisedDevice.getAddress());

@NiekBeijloos
Copy link
Author

Thank you for your advice.

I can delete the Server_BLE_Address after the onResult(BLEAdvertisedDevice advertisedDevice) method has finished. But what about the myAdvertiseDevice ? I need that in my main loop to perform a connect with the pheriperhal: pMyClient-> connect(myAdvertiseDevice->getAddress());.

Hope you can give more clarity on that.
Thank you!

@h2zero
Copy link
Contributor

h2zero commented Mar 29, 2020

I always lamented that piece of code, this repo has an alternative onResult method defined that I suggest you use.

Change:
void onResult(BLEAdvertisedDevice advertisedDevice) {
to:
void onResult(BLEAdvertisedDevice* advertisedDevice) {

Then change all the advertisedDevice. to advertisedDevice->.

And change myAdvertiseDevice = new BLEAdvertisedDevice(advertisedDevice);

To: myAdvertiseDevice = advertisedDevice;

That should solve your memory leaks.

Edit: Forgot a part. Or do as chegewara shows below.

@chegewara
Copy link
Collaborator

BLEAdvertisedDevice* myAdvertiseDevice = nullptr;
....

....
if(myAdvertiseDevice != nullptr)
   delete myAdvertiseDevice;

myAdvertiseDevice = new BLEAdvertisedDevice(advertisedDevice);

@NiekBeijloos
Copy link
Author

Thank you very much! I fixed the memory leak issue!
The suggestions were very helpful!

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

No branches or pull requests

3 participants